2010-07-20 51 views
0

我有一種情況,我希望主線程在等待,而其他線程可以在主線程上調用,而無需調用Application.Run。是否可以在等待的線程上調用?

以下代碼顯示了我嘗試實現的內容,只是主線程和數據加載線程導致了死鎖。

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     var form1 = new Form1(); 
     form1.Show(); 

     Thread loadDataThread = new Thread(() => 
     { 
      //Load Data that takes a long time 
      string title = LoadData(); 
      form1.Invoke((Action)delegate { form1.Text = title; }); 
     }); 

     loadDataThread.Name = "Data Loading Thread"; 
     loadDataThread.Start(); 

     //wait for loading to be completed (deadlock) 
     loadDataThread.Join(); 

     //Do more stuffs 

     Application.Run(); 
    } 

    private static string LoadData() 
    { 
     Thread.Sleep(1000); 
     return "Hello Thread"; 
    } 
} 

謝謝

回答

1

調用僅適用,因爲在Windows窗體應用程序中,應用程序的整個生命週期都有一個消息循環運行。如果您在Thread.Join上被阻塞,則消息循環不處理消息,這也意味着它不處理您的調用調用。

一些在.NET框架,做抽取消息阻塞調用,但你不能(也不應該),因爲更多的往往不是他們在你的應用程序中創建重入的錯誤是依靠這些解決巨大的痛苦。

而不是在等待數據加載時阻塞UI線程,您應該讓它在啓動屏幕顯示的背景下運行。最後,您可以使用BeginInvoke關閉啓動畫面並打開主屏幕或加載結束時需要執行的任何操作。像...

static void Main() { 

    Application.EnableVisualStyles(); 

    var splashScreen = new Form1(); 
    var mainScreen = new Form2(); 

    splashScreen.Show(); 

    ThreadPool.QueueUserWorkItem(delegate { 

     LoadLotsOfData(); 

     splashScreen.BeginInvoke(delegate { 
      splashScreen.Close(); 
      mainScreen.Show(); 
     }); 

    } 

    Application.Run(); 

} 
+0

感謝您的示例。我很好奇其他人如何接近啓動畫面問題。我猜測最終最好是儘快釋放Main(UI)線程,以便其他線程可以通過invoke()與UI進行交互。 – dsum 2010-07-22 04:55:26

+0

沒問題。如果這回答了您的問題,則應通過單擊複選標記將其標記爲已回答。 – Josh 2010-07-28 02:35:21

+0

僅供參考:C#5.0 CTP將有新的語法調用「async」和「await」,這正是我正在尋找的解決上述問題的方法。希望它會使我的代碼更具可讀性,而不是具有所有這些回調。 – dsum 2010-11-22 19:31:49

1

號,需要調用Application.Run,然後計劃在UI線程上的代表。

P.S.使用Task類而不是Control.Invoke更好。

+0

我不知道有一個任務類。我傾向於依靠使用Thread,ThreadPool或調用。謝謝(你的)信息。 我希望Main()代碼執行「出現」線性運行,這將使代碼審查更易於遵循。這會在應用程序初始化時隱藏一些複雜性。 – dsum 2010-07-22 04:27:57

相關問題