为什么Task.Wait()导致应用程序冻结 [英] Why is Task.Wait() causing application to freeze

查看:114
本文介绍了为什么Task.Wait()导致应用程序冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我调用BuildCustomer.StartTask时,我然后调用方法WriteToDatabase.在WriteToDatabase内部,我想将状态发送回MainForm,以将状态写入GUI.当代码到达该点时,我的应用程序冻结并且没有出现错误.我确实发现,如果删除task.Wait(),它将停止冻结并开始工作.但我想我要等待,因为我的BuildCustomer花费了一些时间,并将大量更新(包括来自Common类的更多更新)写入GUI.有人可以告诉我什么地方错了或者我应该做些什么吗?这是一个.Net 4项目,所以我不能使用异步,我已经看到了其他答案.

When I call BuildCustomer.StartTask, I then call a method WriteToDatabase. Inside WriteToDatabase, I want to send a status back to the MainForm to write the status to the GUI. When the code reaches that point, my application freezes up and gives no error. I did find out that if I remove task.Wait(), it stops freezing and works. But I think I want the wait in because my BuildCustomer takes a bit of time and writes a lot of updates (including more updates from Common class) to the GUI. Can someone tell me what is wrong or what I should be doing differently? This is a .Net 4 project so I cannot use async, which I've seen other answers for.

public partial class MainForm : Window
{
    public MainForm()
    {
        Common.SendMessage += UpdateStatus;
    }

    private void Button_Click(object sender, EventArgs e)
    {
        BuildCustomer.StartTask();
    }

    private void UpdateStatus(string message)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            StatusTextBox.Text = message;
        }));
    }
}

public class BuildCustomer
{
    public static void StartTask()
    {
        var action = new Action<object>(BuildCustomer);

        var task = new Task(() => action(buildDetails));

        task.Start();

        task.Wait();
    }

    private void BuildCustomerDetails(object buildDetails)
    {
        Common.WriteToDatabase();
    }
}

public class Common
{
    public delegate void MessageLogDelegate(string message);

    public static event MessageLogDelegate SendMessage;

    public static void WriteToDatabase()
    {
        SendMessage("Some status message to write back to the GUI");
    }
}

推荐答案

您遇到了死锁. StartTask等待task.Wait()完成,但这在作为主UI线程的调用线程上发生(被调用).

You have a deadlock. The StartTask waits on task.Wait() to complete but this occurs (is called on) on the calling thread which is the main UI thread.

正在等待的Task最终会到达UpdateStatus,后者也会在UI线程上调用Invoke,但是该线程当前正在task.Wait()(上等待,因此它被阻塞了,导致UI线程没有被执行无限期可用).

The Task being waited eventually reaches UpdateStatus which calls an Invoke on the UI thread as well but this thread is currently waiting on task.Wait() (so it is blocking which results in the UI thread not being available indefinitely).

这篇关于为什么Task.Wait()导致应用程序冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆