2017-08-11 54 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

相關問題