【初学者求教】线程间操作无效: 从不是创建控件“label1”的线程访问它。

OROCHIORI572 2010-05-10 12:05:04

private void Form1_Load(object sender, EventArgs e)
{
//多线程
AAA= new Thread(new ThreadStart(BBB));
AAA.Start();
}


//接收数据方法
public void BBB()
{
while (true)
{
IPEndPoint IpSender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tmpRemote = (EndPoint)IpSender;

byte[] recive = new byte[1024];
try
{
int recv = bacnet_master_socket.ReceiveFrom(recive, ref tmpRemote);
}
catch (Exception efe)
{
label1.Text = efe.ToString();
}
}
}


我应该怎样写才能把错误信息显示到label1中呢?
希望高手指点!!
感激不尽!!!!!
...全文
2007 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
SuqianHome 2011-04-08
  • 打赏
  • 举报
回复
但是不能接假死的现象 如果耗时10分钟,跨线程使用UI怎么处理
OROCHIORI572 2010-05-11
  • 打赏
  • 举报
回复
感谢各位回复!!学习了
理不完的逻辑 2010-05-10
  • 打赏
  • 举报
回复
学习~!
g394594141 2010-05-10
  • 打赏
  • 举报
回复
你因为是在线程里操作主线程的控件,所以出错,你应该用委托
控件的invoke函数

操作实列请看
http://msdn.microsoft.com/zh-cn/library/zyzhdc6b(v=VS.80).aspx
mngzilin 2010-05-10
  • 打赏
  • 举报
回复
delegate void MyDele();
MyDele del;
private void button1_Click(object sender, EventArgs e)
{
del=new MyDele(BBB);
del.Invoke();
}
public void BBB()
{
while (true)
{
button1.Text = DateTime.Now.ToString();
Application.DoEvents();
}
}
ZengHD 2010-05-10
  • 打赏
  • 举报
回复

上面的错了
private delegate void MyDelegateUI();


if (label1.InvokeRequired)
{
MyDelegateUI d = delegate
{
label1.Text = efe.ToString();
};
label1.Invoke(d);
}
else
{
label1.Text = efe.ToString();
}


skep99 2010-05-10
  • 打赏
  • 举报
回复
用委托实现,论坛里经常问的问题

//catch (Exception efe)
//{
label1.Text = efe.ToString();
//}
//改成
catch (Exception efe)
{
setLabel(efe.ToString());
}



//setLabel方法及委托
delegate void delegateSetLabel(string str);
void setLabel(string str)
{
if (this.InvokeRequired)
{
Invoke(new delegateSetLabel(setLabel), new object[] { str });
}
else
{

label1.Text = efe.ToString();
}
}
lanfengsese 2010-05-10
  • 打赏
  • 举报
回复
委托不错
不是很清楚LZ的问题
ZengHD 2010-05-10
  • 打赏
  • 举报
回复
if (label1.InvokeRequired)
{
label1.Text = efe.ToString();
}
  • 打赏
  • 举报
回复
1.在 public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;//加入这句话,不过治标不治本
}

2.使用委托(根据你的程序创建委托)
takako_mu 2010-05-10
  • 打赏
  • 举报
回复
try catch拿到A外面試試.
mngzilin 2010-05-10
  • 打赏
  • 举报
回复
用委托不就行了
jimeixuehua 2010-05-10
  • 打赏
  • 举报
回复
正解很多了,但是跨线程调用控件一定要用到invoke这个方法,和一个委托!
dreaming47 2010-05-10
  • 打赏
  • 举报
回复
跨线程访问控件的问题么。


很多时候写windows程序都需要结合多线程,经常会跨线程操作控件,这时就会出错,提示不允许"从不是创建控件的进程访问它"。

这个时候的解决思路:把想对另一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数,并且在那个函数中加入一个判断,用InvokeRequired来判断调用这个函数的线程是否和控件线程在同一线程中,如果是则直接执行对控件的操作,否则利用控件的Invoke或BeginInvoke方法来执行这个代理,执行唤醒控件的操作。
Invoke的中文解释是唤醒,它有两种参数类型 (Delegate, Object[])和(Delegate)
Delegate就是前面提到的那个代理,而Object[]则是用来存放Delegate所代理函数的参数


delegate void aa();//定义代理

private void CtlInvoke()
{
if (label1.InvokeRequired)//判断是否需要唤醒操作(当前线程与控件是否属于一个线程,否就执行唤醒,是就执行方法)
{
aa a1 = new aa(label1);//执行代理
label1.Invoke(a1);//执行唤醒操作
}
else
{
return;
}
}
VRC289 2010-05-10
  • 打赏
  • 举报
回复
程里操作主线程的控件,所以出错 可以通过委托来实现
guanmingle 2010-05-10
  • 打赏
  • 举报
回复
在.net中,控件的访问更新只能在"拥有"这个控件的线程上执行,否则回抛异常。

MS在Control类上提供了一个InvokeRequired的属性。下面是MSDN对这个属性的一个注释。我这里只有中文版的。呜呜。

Control.InvokeRequired 属性
获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。

我查过英文版的注释,无论是中文的还是英文的,都强调了一点,就是说控件只能在创建此控件的线程上才能被调用。但是实际上却不是这样子的。

正确地说,这里有两个概念,即创建控件的线程和拥有控件的线程。关于"拥有"这个词,这里只是我自己YY出来的,但愿能说明问题,后面还有更多的解释。

创建控件的线程很好理解,那什么是拥有控件的线程呢。两者是一样的吗?不一样。

拥有控件的线程。我这里指的应该是创建了此控件handle的线程,而不是创建控件本身的那个线程。两者可以是相同的,也可以是不同的。

那线程怎么样创建一个控件的handle呢?很简单,我们还是先看看MSDN对Handle的说明。

Control.Handle 属性

获取控件绑定到的窗口句柄。
备注
Handle 属性的值是 Windows HWND。如果句柄尚未创建,引用该属性将强制创建句柄。

在实际中,当一个控件被创建出来后,它的Handle是还没有被创建的,只有当第一次引用了该发生之后,才会被创建。

mayonglong 2010-05-10
  • 打赏
  • 举报
回复
蛮饶人的~
cuike519 2010-05-10
  • 打赏
  • 举报
回复
你在不是创建UI对象的线程里面访问UI对象。

你可以通过调用UI的invoke方法让方法在主线程(UI线程)中访问UI对象。

具体过程请参考:InvokeRequired属性和Invoke方法的使用。

111,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧