C# 在子線程中創建不會阻塞執行窗體


可以參考”C# 對 Windows 窗體控件進行線程安全調用“一文來看。

在做網絡連接程序的時候碰到一個問題:每當連接到來時,都創建一個新的接收線程,而該接收線程在接收到消息時,可以創建一個新的對話窗口,而該窗口不能阻塞該接收線程的下一輪消息的接收,而且該接收線程還要把接收到的消息顯示在該窗口上

Form.ShowDialog();方法彈出模態對話框,而模態對話框會阻塞后面代碼的執行,導致接收線程無法繼續執行(除非該模態窗口被關閉)

剛開始想到的解決辦法,就是:通過Form.Show();方法,顯示非模態的窗口

非模態對話框有幾個問題:

(1) 生命期限問題:由於是在線程的一輪執行中創建的,所以,該對象可能在該輪結束后被垃圾回收機制自動清除掉;

(2) 模態對話框沒有系統消息機制,需要自己寫;(好像是這樣的,沒用過...)

(3) 在代碼中嘗試了一下,沒有創建消息機制,只是顯示窗口。但該窗口處於假死狀態,根本沒法用。

由於上述的幾個困難,只能另覓它途了...

成功實驗-----異步委托

在看其他文章的時候,偶然看到Control.Invoker()方法,該方法可執行自定義或系統定義的委托。

突然想起來,委托可以通過用Invoke()方法同步執行(阻塞執行),而通過BeginInvoke()方法異步執行,如果是異步執行的話,應該是不會阻塞線程的執行吧...

於是,做了如下的例子:

注意事項:

通過Invoke()/BeginInvoke()調用委托,必須由已經出現的控件來調用,否則會出現錯誤提示:“未經處理的異常:  System.InvalidOperationException: 在創建窗口句柄之前,不能在控件上調用 Invoke 或 BeginInvoke。”

 

1) 打開窗口代碼:

  1. void openNewForm()  
  2. {  
  3.     Form2 newForm = new Form2();  
  4.     newForm.ShowDialog();  
  5. }
  6.  

 

(2) 線程入口函數

  1. //線程入口函數  
  2. void _threadProc()  
  3. {  
  4.     //定義一個委托實例,該實例執行打開窗口代碼  
  5.     MethodInvoker mi = new MethodInvoker(openNewForm);  
  6.     BeginInvoke(mi);  
  7.   
  8.     //如果沒有阻塞的話,該段代碼應該可執行  
  9.     Console.WriteLine("新打開的窗口沒有阻塞之后的執行");  
  10.     Console.ReadLine();  
  11. }  

 

(3) 創建,並執行線程

  1. Thread newThread = new Thread(new ThreadStart(_threadProc));  
  2. newThread.Start(); 

4) 設置項目的輸出類型為:控制台應用程序(這樣執行的時候會同時彈出控制台和窗口)

執行結果如下:

可見,新打開的模式窗口並沒有阻塞線程的執行!

因為,如果是同步調用的話,在Form2窗口關閉之前,“新打開的窗口沒有阻塞之后的執行”就不會有輸出。

 

 

本文非自創,可查看原文:http://blog.csdn.net/xiaobai1593/article/details/7290421

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM