線程間操作無效: 從不是創建控件“”的線程訪問它 解決辦法(轉)


線程間操作無效: 從不是創建控件“”的線程訪問它 解決辦法

http://blog.sina.com.cn/s/blog_568e66230101der7.html

利用FileSystemWatcher設計一個文件監控系統時,如果一個文件被修改或者新建,則文件修改事件會被多次觸發而產生多條信息。為了將一個文件被修改一次而產生的多條信息歸結為一條,在設計中新開了一個線程,在指定時間內(如2秒內)這個文件的修改被認為是一次修改,從而只產生一條信息。

這個工作完成后,又出現了另外一個問題:因為需要在文件修改時,在Listbox控件中新增一條提示信息,代碼是這樣的:

this.lstResults.Items.Add(info);

結果在運行時出現了:線程間操作無效: 從不是創建控件“lstResults”的線程訪問它 這樣的錯誤信息。根據VS2012上的幫助提示,直接進入到MSDN的幫助鏈接 http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(EHInvalidOperation.WinForms.IllegalCrossThreadCall);k(TargetFrameworkMoniker-.NETFramework,Version=v2.0);k(DevLang-csharp)&rd=true

這里提出了線程安全的概念。就本錯誤信息而言,就是說,如果對一個控件的狀態進行改變(比如設置其中的屬性值),那么必須使用創建控件的線程來操作,如果不是創建控件的線程,那么,需要使用代理完成任務。MSDN具體的描述如下:

1、查詢控件的InvokeRequired屬性

2、如果InvokeRequired為true, 使用Invoke調用由委托封裝的該控件操作

3、如果InvokeRequired為false, 直接對該控件進行操作

因此,要解決這個問題,需要

1、定義委托;

2、定義對應委托的方法,這個方法要完成該控件的操作;

3、將原來控件的操作,轉換為調用委托方法的調用;

具體的解決辦法如下:

   //define a delegate
        private delegate void testDelegate(string str);
       
        //define a method which match the above delegae
        private void testMethod(string str)
        {
            // query the control's(here is lstResults) InvokeRequired
            if (this.lstResults.InvokeRequired)
            {
                //instansiate a delegate with the method
                testDelegate myDelegate = new testDelegate(testMethod);
                //Invoke delegate
                this.lstResults.Invoke(myDelegate,str);
            }
            else
            {
                //InvokedRequired is false, so call the control directly
                this.lstResults.Items.Add(str);
            }
        }

 

原來的控件操作代碼:

this.lstResults.Items.Add(info);

改成了線程安全代碼如下:

 //this.lstResults.Items.Add(info);
     //a thread-safe call
     this.testMethod(info);

注意原來的控件操作代碼被注釋,實際操作放在testMethod()方法內。

上述辦法是MSDN推薦的辦法。

 

還有一種最簡單的辦法是改變屬性:

Control.CheckForIllegalCrossThreadCalls = false;

這種辦法直接屏蔽了錯誤信息的出現,一般情況下可以使用,但注意這個已經不是線程安全的辦法了,它只是簡單屏蔽了錯誤信息。

 

 


免責聲明!

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



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