问题
I know I'm missing something stupid, the "StartProcess" Method is making the UI unresponsive and no amount of googling and tutorials has led me to an answer.
Here is my code:
public MainWindow()
{
InitializeComponent();
txtBlock.Text = "Testing";
Initialize();
}
public void Initialize()
{
uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
StartProcess();
}
async void StartProcess()
{
Task<int> result = Task.Factory.StartNew(() =>
{
txtBlock.Text += ("\n starting updater");
while (true)
{
Thread.Sleep(3000);
}
return 0;
}, CancellationToken.None, TaskCreationOptions.LongRunning, uiScheduler);
}
Some background: I'm building an app that has to poll the DB every 5mins and update the UI with a to-do list for the user, hence the while(true) loop. The app has to poll the DB continuously throughout its lifetime.
回答1:
Well, you asked the TPL to invoke the Func
in UI thread, it obeys your words.
In StartNew you pass uiScheduler
as TaskScheduler
, so the task will be queued to Dispatcher
which will be invoked by UI thread.
If you don't want to execute in UI thread then use TaskScheduler.Default
, doing so you can't update txtBlock.Text
inside the Func
. You need to marshal the call to UI thread or just set the txtBlock.Text
outside the Func
before StartNew
.
Always prefer Task.Run
if you're in .Net 4.5, be aware that StartNew is dangerous.
Couple of things to note:
- Note that you're not leveraging the
async
feature at all. Without anawait
keyword method is not at all async. You don't need the async keyword at all(Infact you'll get a compiler warning, please pay attention to what compiler says). - Avoid async void methods(Except in event handlers), always use
async Task
if you don't need any return value, so that you could await it in the caller or attach continuation and so forth.
Update to add some code:
async Task StartProcess()
{
while (true)
{
var result = await Task.Run(()=> MethodWhichCallsDBAndReturnsSomething());
txtBlock.Text = result.ToString();//Use result and update UI
await Task.Delay(5 * 60 * 1000);//await 5 mins
}
}
来源:https://stackoverflow.com/questions/25769078/wpf-async-task-locking-ui