跨线程操作Treeview
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨线程操作Treeview相关的知识,希望对你有一定的参考价值。
定义了一个线程用来出发一个时间,当一个用户发送一条消息的时候,他将调用这个线程,然后线程将触发一个事件,通知收消息人,在收消息的时候如果有新消息则在TreeView中添加TreeNode显示新消息内容,但是现在有问题了,他报出的错误是:
参考技术A 这个错误应该是跨线程调用控件的问题。默认情况下子线程不能直接调用主线程的控件,你在窗体的构造函数里面加一行代码:Form.CheckForIllegalCrossThreadCalls = false;不行的话就要按系统的提示使用委托了 参考技术B 用InvokeRequired判断一下,给你写了一个例子,如果你嫌声明委托麻烦也可以直接用EventHandler,EventArgs为null就可以了。
delegate void MyEvent(string value);//代理事件
//子线程
private void MyThread()
for (int i = 0; i < 10; i++)
System.Threading.Thread.Sleep(100);
ValueAdd(i.ToString());//抛出一个数据
private void ValueAdd(string value)
if (this.InvokeRequired)//判断是否需要Invoke
MyEvent OnEvent = ValueAdd;
this.Invoke(OnEvent, new object[] value );//如果需要则将这个数据交给创建控件的线程去处理
else
listBox1.Items.Add(value);
本回答被提问者采纳
跨线程操作无效[重复]
【中文标题】跨线程操作无效[重复]【英文标题】:Cross-thread operation not valid [duplicate] 【发布时间】:2011-06-29 13:51:45 【问题描述】:可能重复:Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
好的,我知道为什么会出现这个错误:
跨线程操作无效: 从线程访问的控件“Form1” 除了它创建的线程 开。
但是...我怎样才能使它可行?
System.Threading.Thread t = new System.Threading.Thread(()=>
// do really hard work and then...
listView1.Items.Add(lots of items);
lots more UI work
);
t.Start();
我不在乎线程何时或如何完成,所以我并不真正关心任何花哨或过于复杂的 atm,除非在新线程中使用 UI 时它会使事情变得更容易。
【问题讨论】:
这个问题已经被问过很多次了。看看这个:***.com/questions/1523878/…或***.com/questions/1485786/…或***.com/questions/1377529/…或***.com/questions/1397370/…或***.com/questions/4010602/…或***.com/questions/3439065/… +1 @blue,是的,似乎有一整类关于这方面的类似问题都以略有不同的方式提出,但具有相同的核心思想,即必须在同一个线程上执行 UI 操作。 【参考方案1】:当您从另一个线程访问 from 的属性时,会引发此异常。 要解决此问题,至少有 2 个选项。
告诉 Control 不要抛出这些异常(不推荐):
Control.CheckForIllegalCrossThreadCalls = false;
使用线程安全函数:
private void ThreadSafeFunction(int intVal, bool boolVal)
if (this.InvokeRequired)
this.Invoke(
new MethodInvoker(
delegate() ThreadSafeFunction(intVal, boolVal); ));
else
//use intval and boolval
【讨论】:
【参考方案2】:你不能。 UI 操作必须在所属线程上执行。期间。
您可以做的是在子线程上创建所有这些项目,然后调用 Control.Invoke
并在那里进行数据绑定。
或者使用BackgroundWorker
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, e) => /* create items */ ;
bw.RunWorkerCompleted += (s, e) => /* databind UI element*/ ;
bw.RunWorkerAsync();
【讨论】:
啊,太好了。非常感谢@Adam。 可靠的答案,但我很好奇为什么“你不能”是真的。你有进一步的阅读吗?以上是关于跨线程操作Treeview的主要内容,如果未能解决你的问题,请参考以下文章
例外:跨线程操作无效:控制'pgImportProcess(进度条)'从一个线程访问,而不是它在[重复]上创建的线程