当前位置:首页 » 密码管理 » 从不是创建控件的线程访问它

从不是创建控件的线程访问它

发布时间: 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方法,并传入需要的参数完成相应操作,否则可以直接对该控件对象进行操作

热点内容
sqlserver2008查询时间 发布:2025-05-11 04:15:28 浏览:386
安卓孤胆车神被封号怎么解封 发布:2025-05-11 04:05:22 浏览:940
高压洗车泡沫怎么配置 发布:2025-05-11 04:00:47 浏览:547
腾讯轻量服务器怎么使用 发布:2025-05-11 03:52:46 浏览:174
4位密码组合有多少种至少有一个0 发布:2025-05-11 03:44:03 浏览:338
八卦手指算法 发布:2025-05-11 03:23:32 浏览:281
编译成exe是什么意思 发布:2025-05-11 03:23:28 浏览:470
javaweb技术内幕 发布:2025-05-11 03:20:14 浏览:803
多台焊机变压器怎么配置 发布:2025-05-11 03:18:07 浏览:310
nmake编译 发布:2025-05-11 03:04:32 浏览:622