1. 程式人生 > >C#執行緒之間操作無效|不允許訪問控制元件(c# 執行緒間操作無效: 從不是建立控制元件“”的執行緒訪問它)

C#執行緒之間操作無效|不允許訪問控制元件(c# 執行緒間操作無效: 從不是建立控制元件“”的執行緒訪問它)

解決方法
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