C#混合使用Task和Dispatcher.Invoke,为什么会停止?

时间:2021-09-09 19:48:01

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());