跨线程操作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(进度条)'从一个线程访问,而不是它在[重复]上创建的线程

跨线程操作无效:控件“statusStrip”从创建它的线程以外的线程访问

C#跨线程操作控件的最简单实现探究