C#執行緒之間操作無效|不允許訪問控制元件(c# 執行緒間操作無效: 從不是建立控制元件“”的執行緒訪問它)
阿新 • • 發佈:2019-02-01
解決方法
1.建立事件委託
c#不允許對跨執行緒的控制元件的訪問,如需操作跨執行緒的操作需要通過委託(delegate),即是函式指標來操作跨執行緒。說明dgList控制元件不是該執行緒的控制元件,需要使用委託操作。比如:
delegate void SetListBoxCallback(string str); //定義委託(SetListBoxCallback名稱可以變化,自己定義) public void SetListBox(string str) { if (listBoxInfo.InvokeRequired) //控制元件是否跨執行緒?如果是,則執行括號裡程式碼 { SetListBoxCallback setListCallback = new SetListBoxCallback(SetListBox); //例項化委託物件 listBoxInfo.Invoke(setListCallback, str); //重新呼叫SetListBox函式(新建立的委託進行相應控制元件的操作 } else //否則,即是本執行緒的控制元件,控制元件直接操作 { listBoxInfo.Items.Add(str); //具體的控制元件操作。eg:textBox1.Text+=str; } }
在MSDN裡面可以找到,關鍵字:執行緒安全
委託名可以自己定義,
(如果你直接執行,那麼就是從子執行緒呼叫主執行緒的方法執行你的操作,這樣是不允許的。
雖然沒人告訴我這是為什麼,但是我覺得(很多執行緒同時呼叫)那樣可能會導致死鎖的情況。
舉例說,我是主執行緒,電腦是子執行緒,我能夠控制子執行緒怎麼操作,可是你能讓電腦控制我嗎?顯然不能,也不可能。
那為什麼引用就可以呢?引用是什麼?
引用就是方法的別名,如果你打過遊戲,可以理解這是方法的一個副本。
每個執行緒建立一個我的副本,那麼就可以執行了,不會出現爭搶,死鎖的情況。)
一樓執行緒安全程式碼的解釋是這樣的:
定義一個委託
建立一個方法 //在需要執行緒操作的地方呼叫此方法
{
如果某一個操作需呼叫主執行緒的該方法
給他建立一個該方法的副本,呼叫該方法的副本執行操作
如果並沒有呼叫主執行緒操作
直接執行【你需要的操作】 //在此你需要的操作即在主執行緒上進行的操作
}
2.建立執行緒(需要補全,實操未通過)
void XXXXXX()
{
ThreadStart X;
X= new ThreadStart(func); //將類的方法繫結X。
Thread Y=new Thread(Y); //建立新執行緒
Y.Start();//執行緒開始
}
void func(XXXXXXXXX) //類的一個方法
{
//對相應控制元件進行操作
}
ThreadStart是一個delegate