欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
對 Windows 窗體控件進(jìn)行線(xiàn)程安全調用 - 夜淡茶清.shenfx - 博客園

對 Windows 窗體控件進(jìn)行線(xiàn)程安全調用

今天在編寫(xiě)一個(gè)windows應用程序的時(shí)候碰到了一個(gè)小問(wèn)題,程序需求是這樣的,創(chuàng )建多個(gè)線(xiàn)程調用執行某個(gè)方法,WindowsForm中有個(gè)Progress Bar控件用于顯示已經(jīng)執行完畢的進(jìn)程數,即當所有的線(xiàn)程都運行完畢后,ProgressBar的進(jìn)度也到頭了。先給出初步的實(shí)現方式:

 

 1         private const int MAXTHREAD = 100//最大線(xiàn)程數
 2         private int n = 0, count = 0//實(shí)際線(xiàn)程數、已結束的線(xiàn)程數
 3 
 4         private void StartTest()
 5         {
 6             n = int.Parse(txtThreadCount.Text); //線(xiàn)程數
 7             progressBar1.Maximum = n * 10//設置ProgressBar的最大值
 8 
 9             Thread thread = null;
10             List<Thread> threads = new List<Thread>(MAXTHREAD);
11             ReadTableTest t = new ReadTableTest(tableName, fileds); 
12             t.ThreadExitEvent += new ThreadExit(OnThreadExit); //線(xiàn)程執行完畢后通知主界面
13 
14             try
15             {
16                 //創(chuàng )建線(xiàn)程
17                 for (int i = 0; i < n; i++)
18                 {
19                     thread = new Thread(new ThreadStart(t.Run));
20                     threads.Add(thread);
21                 }
22 
23                 //開(kāi)始調用接口
24                 foreach (Thread tt in threads)
25                 {
26                     tt.Start();
27                 }
28             }
29             catch (Exception ex)
30             {
31                 MessageBox.Show(ex.Message);
32             }
33         }
34 
35         //線(xiàn)程執行完畢后回調
36         public void OnThreadExit()
37         {
38             count++;
39             this.progressBar1.Value = count * 10//設置ProgressBar的進(jìn)度
40 
41             //判斷是否全部進(jìn)程已結束
42             if (count == n)
43             {
44                 MessageBox.Show("所有線(xiàn)程已執行完畢!");
45                 ClearState();
46             }
47         }

當調試執行這段程序時(shí)在this.progressBar1.Value = count * 10;處,報出了InvalidOperationException Cross-thread operation not valid異常,在網(wǎng)上搜索一番后,發(fā)現產(chǎn)生該問(wèn)題的原因如下。

問(wèn)題原因

由于 Windows窗體控件本質(zhì)上不是線(xiàn)程安全的。因此如果有兩個(gè)或多個(gè)線(xiàn)程適度操作某一控件的狀態(tài)(setvalue),則可能會(huì )迫使該控件進(jìn)入一種不一致的狀態(tài)。還可能出現其他與線(xiàn)程相關(guān)的bug,包括爭用和死鎖的情況。于是在調試器中運行應用程序時(shí),如果創(chuàng )建某控件的線(xiàn)程之外的其他線(xiàn)程試圖調用該控件,則調試器會(huì )引發(fā)一個(gè)InvalidOperationException

解決方案

對于該異常的解決方案有兩種,一種是關(guān)閉該異常檢測的方式來(lái)避免異常的出現,經(jīng)過(guò)測試發(fā)現此種方法雖然避免了異常的拋出,但是并不能保證程序運行結果的正確性,對于此例來(lái)說(shuō),經(jīng)常是全部線(xiàn)程結束時(shí),進(jìn)度條的顯示還未到頭呢。下面再來(lái)看看更加優(yōu)雅的解決方案,即通過(guò)保證線(xiàn)程的安全性來(lái)避免該異常,先來(lái)看看兩種方案的代碼。

方案1 

1         public Form1()
2         {
3             InitializeComponent();
4             Control.CheckForIllegalCrossThreadCalls = false;
5         }

 

說(shuō)明

關(guān)閉CheckForIllegalCrossThreadCalls,這是Control class上的一個(gè)staticproperty,默認值為flase,目的在于開(kāi)關(guān)是否對Handle的可能存在的不一致存取的監測;且該項設置是具有Applicationscope的。

方案2 

 1 //未給出代碼的部分沒(méi)有變化
 2         private delegate void SafeSetProgressBarValue(int v);
 3 
 4         //線(xiàn)程執行完畢后回調
 5         public void OnThreadExit()
 6         {
 7             count++;
 8             OnSafeSetValue(count * 10); //使用線(xiàn)程安全的代碼設置ProgressBar的進(jìn)度
 9 
10             //判斷是否全部進(jìn)程已結束
11             if (count == n)
12             {
13                 MessageBox.Show("所有線(xiàn)程已執行完畢!");
14                 ClearState();
15             }
16         }
17 
18         /// <summary>
19         /// 線(xiàn)程安全的修改ProgressBarValue方式。
20         /// </summary>
21         /// <param name="va"></param>
22         private void OnSafeSetValue(int va)
23         {
24             
25             if (this.progressBar1.InvokeRequired)
26             {
27                 SafeSetProgressBarValue call = delegate(int v) { this.progressBar1.Value = v; };
28  
29                 this.progressBar1.Invoke(call,va);
30             }
31             else
32                 this.progressBar1.Value = va;
33         }

 說(shuō)明

Windows窗體中的控件被綁定到特定的線(xiàn)程,不具備線(xiàn)程安全性。因此,如果從另一個(gè)線(xiàn)程調用控件的方法,那么必須使用控件的一個(gè) Invoke方法來(lái)將調用封送到適當的線(xiàn)程。該屬性可用于確定是否必須調用 Invoke方法,當不知道什么線(xiàn)程擁有控件時(shí)這很有用??丶嫌兴姆N方法可以安全地從任何線(xiàn)程進(jìn)行調用:Invoke、BeginInvoke、EndInvoke和 CreateGraphics。對于所有其他方法調用,當從另一個(gè)線(xiàn)程進(jìn)行調用時(shí),應使用這些 Invoke 方法之一。

Control.InvokeRequired 屬性

獲取一個(gè)值,該值指示調用方在對控件進(jìn)行方法調用時(shí)是否必須調用 Invoke 方法,因為調用方位于創(chuàng )建控件所在的線(xiàn)程以外的線(xiàn)程中。

屬性值

如果控件的 Handle 是在與調用線(xiàn)程不同的線(xiàn)程上創(chuàng )建的(說(shuō)明您必須通過(guò) Invoke 方法對控件進(jìn)行調用),則為 true;否則為 false。

更多資料:

http://msdn2.microsoft.com/zh-cn/library/ms171728(VS.80).aspx

http://msdn2.microsoft.com/zh-cn/library/system.windows.forms.control.invokerequired(VS.80).aspx

http://blog.csdn.net/joem/archive/2006/12/18/1448198.aspx

posted on 2007-02-08 20:47 shenfx 閱讀(679) 評論(0)  編輯 收藏 引用 網(wǎng)摘 所屬分類(lèi): 問(wèn)題解決

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
談.Net委托與線(xiàn)程——解決窗體假死 - 橫豎都溢 - 博客園
InvokeRequired 屬性 與Invoke方法(轉)
.net開(kāi)發(fā)筆記(十八) winform中的等待框
WPF:如何在工作線(xiàn)程中更新窗體的UI元素(Dispatcher機制)
多線(xiàn)程編程(4):多線(xiàn)程與UI操作
InvokeRequired and Invoke - jacky的日志 - 網(wǎng)易博客
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久