I tried below snippet:
我试过下面的片段:
public Task RunUiTask(Action action)
{
var task = Task.Factory.StartNew(() =>
{
Dispatcher.Invoke(DispatcherPriority.Background, action);
});
return task;
}
private void OnCreateTask(object sender, RoutedEventArgs e)
{
var task = RunUiTask(() =>
{
for(int i=0;i<10;i++)
{
ResultTextBlock.Text += i.ToString();
}
});
task.Wait(); //(a) Program stopped here
ResultTextBlock.Text += "Finished"; //(b) Never called;
}
I couldn't understand why, when OnCreateTask (a button click event handler) is called, the program halts at (a), and (b) is never called.
我无法理解为什么,当调用OnCreateTask(按钮单击事件处理程序)时,程序在(a)处停止,并且(b)从不被调用。
Note: I know I can use Dispatcher.BeginInvoke to make program responsive, but this is not my concern here.
注意:我知道我可以使用Dispatcher.BeginInvoke来使程序响应,但这不是我关注的问题。
Can any body tell why the program halts at (a), and why (b) is never called? Thanks.
任何人都可以告诉为什么程序在(a)处停止,为什么(b)从未被调用?谢谢。
1 个解决方案
#1
6
The call of
呼唤
Dispatcher.Invoke(DispatcherPriority.Background, action);
will execute Action
in your UI Thread and will return after Action
is executed. The Problem is, that your UI Thead is blocked because of the task.Wait()
in your OnCreateTask
, so the Action will never be executed and you have a Deadlock.
将在您的UI线程中执行Action,并在执行Action后返回。问题是,由于OnCreateTask中的task.Wait(),你的UI Thead被阻止了,所以Action永远不会被执行而你有一个死锁。
EDIT
Instead of your task.Wait()
you should use a Continuation and Update ResultTextBlock.Text
而不是你的task.Wait(),你应该使用Continuation和Update ResultTextBlock.Text
task.ContinueWith(t=>{
ResultTextBlock.Text += "Finished";
}, TaskScheduler.FromCurrentSynchronizationContext());
#1
6
The call of
呼唤
Dispatcher.Invoke(DispatcherPriority.Background, action);
will execute Action
in your UI Thread and will return after Action
is executed. The Problem is, that your UI Thead is blocked because of the task.Wait()
in your OnCreateTask
, so the Action will never be executed and you have a Deadlock.
将在您的UI线程中执行Action,并在执行Action后返回。问题是,由于OnCreateTask中的task.Wait(),你的UI Thead被阻止了,所以Action永远不会被执行而你有一个死锁。
EDIT
Instead of your task.Wait()
you should use a Continuation and Update ResultTextBlock.Text
而不是你的task.Wait(),你应该使用Continuation和Update ResultTextBlock.Text
task.ContinueWith(t=>{
ResultTextBlock.Text += "Finished";
}, TaskScheduler.FromCurrentSynchronizationContext());