2017-08-11 56 views
-5

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

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"); 
    } 
} 
+5

你想知道为什么,当你告诉你的UI线程坐在那里,什么也不做,而不是执行任何其他UI动作,直到你给定的任务已经完成,它坐在那里,不执行任何其他UI动作,直到你的任务已完成? – Servy

+0

@CamiloTerevinto'StartNew'在这种情况下,因为它是4.0,而不是4.5,但除此之外,是的。 – Servy

+0

我认为Task.Run()可能不适合你,但Task.StartNew()应该是,我会使用它。你也有一些错误,我认为编译器应该抓住。 – zzxyz

回答

5

你有一个死锁。 StartTasktask.Wait()上等待完成,但在主UI线程的调用线程上发生这种情况(被调用)。

Task正在等待最终达到UpdateStatus其在UI线程调用一个调用很好,但这个线程正在等待task.Wait()因此被阻断,导致不被提供的UI线程无限期)。

+0

感谢您的解释。 – Wannabe

0

尝试异步关键字添加到方法签名,并使用此:

await task; 

导致其不睡觉主线程(UI线程)。

+0

如果没有附加组件,我不能使用异步。 – Wannabe

相关问题