我对委托的理解是一个函数指针,将某个方法的指针交给一个委托,然后由委托根据指针找到创建方法的线程去安全的调用方法。
疑问1:异步委托是否新开线程了。
疑问2:
当用子线程更新主线程控件状态时考虑到线程安全性一般都这样做。
1 ***某线程的方法里*** 2 3 this.Invoke(New Action(()=>{ 4 lable1.Text="111"; 5 })); 6 7 ***某线程的方法里***
在winform里,按钮控件的点击事件是属于主线程的。所以效果都是同步的。因此当触发按钮的点击事件执行button1_click时并没有跨线程。所以更新控件直接赋值即可,不必用Invoke方式(按钮事件也是个委托,此处暂且不考虑委托对线程安全起到的作用,因为根本没跨线程)。
而在winform里,BackGroundWorker这个控件执行时就是跨线程的了,他会异步的执行操作,在操作完成时触发RunWorkerCompleted事件。使用时只要注册RunWorkerCompleted事件,在这个事件触发我的方法时直接给控件赋值即可,也不必用Invoke考虑线程安全性。这里我有点疑惑。之所以不必用Invoke,是否就是RunWorkerCompleted这个事件(也是个委托),以线程安全的方式调用的我的方法,所以不必在我的方法里用Invoke。
如果是,那为什么我自定义的这个情况就出错了。
我的事件触发定义的方法后,为什么就不是线程安全了?
你把 Control.Invoke 同 Delegate.Invoke(BeginInvoke) 的作用搞混淆了,它们不是一个路数的。
因为创建你窗体上控件的是主线程,但是你当前调用的方法是用另一个线程来调用,因此会报异常。
lblLoopTimes.Invoke(new Action(()=>{lblLoopTimes.Text=_loopTimes.ToString()}));
对于多线程必须用invoke方法
可是方法也是通过事件触发调用的啊,委托调用是线程安全的啊。BackgroundWorker也会异步执行啊。为什么他的完成事件里就可以不用Invoke的方式?
另外问个问题。lblLoopTimes.Invoke(...) 和 主线程this.Invoke是一样的吧? 都是主线程去Invoke
Control.Invoke 同 Delegate.Invoke(BeginInvoke) 这是两个概念