當前位置:首頁 » 密碼管理 » 從不是創建控制項的線程訪問它

從不是創建控制項的線程訪問它

發布時間: 2022-04-26 15:23:42

① c# 線程間操作無效: 從不是創建控制項「」的線程訪問它。

樓上已經解釋的很清楚了,VS2005以上版本跨線程處理。
在MSDN裡面可以找到,關鍵字:線程安全
委託名可以自己定義,
listBoxInfo 可以換成你的dgList。
(如果你直接執行,那麼就是從子線程調用主線程的方法執行你的操作,這樣是不允許的。
雖然沒人告訴我這是為什麼,但是我覺得(很多線程同時調用)那樣可能會導致死鎖的情況。
舉例說,我是主線程,電腦是子線程,我能夠控制子線程怎麼操作,可是你能讓電腦控制我嗎?顯然不能,也不可能。
那為什麼引用就可以呢?引用是什麼?
引用就是方法的別名,如果你打過游戲,可以理解這是方法的一個副本。
每個線程創建一個我的副本,那麼就可以執行了,不會出現爭搶,死鎖的情況。)

一樓線程安全代碼的解釋是這樣的:
定義一個委託
創建一個方法
{
如果某一個操作需調用主線程的該方法
給他創建一個該方法的副本,調用該方法的副本執行操作
如果並沒有調用主線程操作
直接執行【你需要的操作】
}

如果,你還不能理解,我只能說,I'm sorry.I do my best!

② VB.NET 在線程里用textbox,提示 線程間操作無效: 從不是創建控制項「TextBox2」的線程訪問它

比如在一個窗體中的代碼如下,在另一個線程中顯示,隱藏窗口線程中的進度條:

PublicDelegateSubVoidDelegate()'定義委託類型
PrivateSubButton1_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)
Dimth1AsNewSystem.Threading.Thread(AddressOfMyThreadProc)'聲明線程
th1.Start()'啟動線程運行MyThreadProc過程
EndSub
PublicSubMyThreadProc()
Me.Invoke(NewVoidDelegate(AddressOfStartProgress))'這個是在另一個線程里調用StartProgress過程,並在創建窗口的那個線程里運行。參數是委託類型。me也可以改成控制項名。如果直接調用StartProgress,那該過程就在與MyThreadProc同一線程中運行,那麼StartProgress過程中修改的控制項不是在本線程創建的,就會出錯。
'。。。。。。。。。
Me.Invoke(NewVoidDelegate(AddressOfShutProgress))
EndSub
PublicSubShutProgress()
ProgressBar1.Visible=False
EndSub
PublicSubStartProgress()
ProgressBar1.Visible=True
EndSub

'不是還有個Process控制項嗎,好像也是用來多線程操作的,還沒研究,

③ 線程間操作無效: 從不是創建控制項「textBox1」的線程訪問它.關於tcpip通信問題

private void SetText()
{
if(textBox1.InvokeRequired)
{
action d = new action(SetText);//系統自帶的委託 不帶參數
this.invoke(d);
}
else
{
textBox1.Text = recvStr;
}
}

//定義委託

private delegate void SetTextHander();//不帶參數
private delegate void SetTextHander(string recvStr);//帶參數

private void SetText(string recvStr)
{
if(textBox1.InvokeRequired)
{
SetTextHanderd = new SetTextHander(SetText);//系統自帶的委託 帶參數
this.invoke(d,new object[]{recvStr});
}
else
{
textBox1.Text = recvStr;
}
}

④ 教你如何解決「線程間操作無效: 從不是創建控制項的線程訪問它」

這個時候程序會卡,當程序員將這些卡代碼放進線程(Thread)中後發現當對控制項操作時出現「線程間操作無效: 從不是創建控制項的線程訪問它」異常。 為什麼.net不讓我們跨線程操作控制項,這是有好處的。因為如果你的線程多了,那麼當兩個線程同時嘗試將一個控制項變為自己需要的狀態時,線程的死鎖就會發生。但是難道就是因為這個原因,我們就只能讓程序卡著么?當然不是,這里教大家一個解決方案:用BackGroundWorker 這里通過一個實例來告訴大家BackGroundWorker的用法。 首先我們先定義一個BackGroundWorker,大家可以去面板上拖一個,也可以自己手工定義一個。
this.backgroundWorker_Combo = new System.ComponentModel.BackgroundWorker();//定義一個backGroundWorkerthis.backgroundWorker_Combo.WorkerSupportsCancellation = true;//設置能否取消任務 this.backgroundWorker_Combo.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_Combo_DoWork);//讓backgroundWorker做的事this.backgroundWorker_Combo.RunWorkerCompleted += new System.ComponentModel.(this.backgroundWorker_Combo_RunWorkerCompleted);//當backgroundWorker做完後發生的事件 如果是從面板上拖的,那麼請在DoWork事件上雙擊,添加那些你想在背景線程中執行的代碼,也就是那些可能會讓你卡的代碼。 然後再在RunWorkerCompleted事件上雙擊,添加那些你想往控制項里操作的代碼。 這里有一個開發實例,講的是實現類似Google搜索中下拉列表的實現。其思路是在DoWork中搜索資料庫,在Completed中將搜出來的東西放進去。 本文需要一個backgroundWorker,一個ComboBox控制項 static char x;
/**//// /// 接受從DLL搜出來的項目
/// private string[] global_ListItem;
private void backgroundWorker_Combo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{//如果數組中有東西,那麼加入ComboBox if (global_ListItem.Length>0){this.comboBox_App.Items.Clear();
this.comboBox_App.Items.AddRange(global_ListItem);
} } private void backgroundWorker_Combo_DoWork(object sender, DoWorkEventArgs e){global_ListItem = Form_Setting.Global_DBC.SimilarFilter(x); //這是一個DLL中的方法,用於查找所有以X打頭的項目,並放入一個數組中 } private void comboBox_App_TextChanged(object sender, EventArgs e)
{//當用戶鍵入一個字母時去資料庫查 ComboBox cb = sender as ComboBox;
if (cb.Text.Length==1){x = cb.Text[0];
} } 那麼是不是用Thread就不行呢?其實不是的,.net中也有線程安全的控制項訪問。

⑤ 求解:線程間操作無效: 從不是創建控制項「tbxRes」的線程訪問它。

//建立個委託
private
delegate
string
returnStrDelegate();
//搞個最簡單滴取值滴方法
private
string
returnSchool()
{
return
CB_School.SelectedValue.ToString();
}
//判斷一下是不是該用Invoke,不是就直接返回
private
string
returnCB(returnStrDelegate
myDelegate)
{
if
(this.InvokeRequired)
{
return
(string)this.Invoke(myDelegate);
}
else
{
return
myDelegate();
}
}

⑥ C#使用線程還是出現:線程間操作無效: 從不是創建控制項「label4」的線程訪問它。

不能從線程里直接使用this.label4.Text = shun_liuliang + "\r\n";這種的東西
因為UI控制項操作不是線程安全的
如果要通過線程更改UI,需要使用invoke來做
1.在Form里寫一個更改UI的函數

2.聲明一個代理,這個代理可以代理這個更改UI的函數

3.函數內部

if(this.label4.invokerequied)//判斷是否需要invoke操作
{
//實例化此函數自身的代理
//如果此函數有參數,需要創建一個數組,按參數數量和順序存放參數
//使用this.label4.begininvoke(代理,參數)來申請UI更新

}
else
{
//更新代碼,如this.label4.Text = shun_liuliang + "\r\n";

}

4.線程中,在要更新的地方調用這個函數即可

⑦ 【c#高手請進!!!】從不是創建控制項的線程訪問它 修改方法

這就是你在線程里使用了控制項的原因,好像控制項都屬於主線程的,所以子線程就不能直接用了,如你所說建立委託就行了 我就認為listBoxaccept是那個控制項了
加上如下代碼:
private delegate void myDelegate(string str);
private void setRich(string str)
{
if (this.listBoxaccept.InvokeRequired)
{
myDelegate md = new myDelegate(this.setRich);
this.Invoke(md, new object[] { str });
}
else
this.listBoxaccept.Items.Add(str);
}
然後將listBoxaccept.Items.Add(richTextBoxaccept.Text);
改為this.setRich(richTextBoxaccept.Text);
哦了

⑧ 線程間操作無效,顯示:從不是創建控制項"Form1"的線程訪問它,是什麼原因

背景:
winform(vs2010)前台界面上有2個group(group1,group2),
每個group上面有一些lable用於顯示後台查詢出來的數據,後台3個線程A,B,C
A線程每隔幾秒查詢資料庫,並把查詢出來的數據更新到group1上的lable上(定義),
B線程每隔幾秒查詢資料庫,並把查詢出來的數據更新到group2上的lable上,通過一個輔助線程計算出的一個值賦給textBox1.text;

1.直接在窗體的構造函數中添加:

System.Windows.Forms.Control. = false;

此時禁用了所有的控制項合法性檢查。

2.通過代理來解決(msdn)

private delegate void SetTextCallback(string text); //在給textBox1.text賦值的地方調用以下方法即可 private void SetText(string text) { // InvokeRequired需要比較調用線程ID和創建線程ID // 如果它們不相同則返回true if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } }

這里主要用到了.NET中的 delegate。

另外如果線程AB只負責將數據保存在全局變數里,用一個有操作許可權的C(主界面搞個timer)調用這些數據並顯示在界面上就沒問題了。

⑨ 從不是創建控制項「combobox」 的線程訪問它

使用委託來實現跨線程調用控制項。
1. 定義一個委託,然後定義一個委託對象。
private delegate void myDel();
private myDel showDel = null;
2. 把你上面的調用代碼寫到一個函數中,比如函數show中
private void show()
{
switch (comboBox1.SelectedIndex)
{
case 0:
MessageBox.Show("0");
break;
case 1:
MessageBox.Show("1");
break;
}
}
3. 用這個函數來實例化委託
showDel= new myDel(show);
3. 在你的不是創建控制項的線程中,調用委託來實現訪問控制項。
即this.Invoke(showDel);

完畢

⑩ c#網路編程點對點網路聊天中出現:線程間操作無效:從不是創建控制項「richTextBox1」的線程訪問它。為什麼

默認情況下,C#不允許在一個線程中直接操作另一個線程中的控制項,這是因為訪問Windows窗體控制項本質上不是線程安全的。如果有兩個或多個線程操作某一控制項的狀態,則可能會迫使該控制項進入一種不一致的狀態。還可能出現其他與線程相關的bug,以及不同線程爭用控制項引起的死鎖問題。因此確保以線程安全方式訪問控制項非常重要。
在調試器中運行應用程序時,如果創建某控制項的線程之外的其他線程試圖調用該控制項,則調試器會引發一個InvalidOperationException異常,並提示消息:「從不是創建控制項的線程訪問它」。
但是在Windows應用程序中,為了在窗體上顯示線程中處理的信息,我們可能需要經常在一個線程中引用另一個線程中的窗體控制項。比較常用的辦法之一是使用委託(delegate)來完成這個工作。
為了區別是否是創建控制項的線程訪問該控制項對象,Windows應用程序中的每一個控制項對象都有一個InvokeRequired屬性,用於檢查是否需要通過調用Invoke方法完成其他線程對該控制項的操作,如果該屬性為true,說明是其他線程操作該控制項,這時可以創建一個委託實例,然後調用控制項對象的Invoke方法,並傳入需要的參數完成相應操作,否則可以直接對該控制項對象進行操作

熱點內容
雷神g50如何設置安卓原生模式 發布:2024-05-19 16:50:04 瀏覽:120
c語言小數四捨五入 發布:2024-05-19 16:23:28 瀏覽:525
資料庫被注入攻擊 發布:2024-05-19 16:21:31 瀏覽:835
微信忘記密碼從哪裡看 發布:2024-05-19 16:06:37 瀏覽:33
寶馬x4貸款買哪個配置好 發布:2024-05-19 15:56:03 瀏覽:23
微控pid演算法 發布:2024-05-19 15:46:31 瀏覽:136
雲盤視頻解壓密碼 發布:2024-05-19 15:23:17 瀏覽:848
和平精英怎麼改地區位置安卓 發布:2024-05-19 15:19:05 瀏覽:286
酒店的路由器如何配置 發布:2024-05-19 15:10:44 瀏覽:502
rpgmaker腳本 發布:2024-05-19 14:48:58 瀏覽:409