本帖最后由 iloli 于 2013-10-30 22:46:52 编辑

解决方案 »

  1.   

    本帖最后由 caozhy 于 2013-10-30 22:48:36 编辑
      

  2.   


    呵呵 版主驾临,感谢感谢。我现在脑中是一点办法都没有。我知道可以在UI线程中使用控件的invoke方法来做,但由于我的通讯类中定义了事件,主UI中接收这些事件,通过事件修改UI中的控件。但由于这些事件是在新的线程中被执行的,所以我必须在UI线程中定义一大堆委托来实现invoke。这样用起来很累。所以我想在我的通讯中就把这个线程切换工作完成掉,这样在主UI中的事件响应方式里就跟普通FORM控件的事件一样使用,不使用再用委托来修改UI上的控件了。。唉,,
      

  3.   

    你要操作ui线程,那么这些实际的操作还是得写在ui线程中。而委托只不过是告诉ui什么时候执行这些操作。
      

  4.   

    对啊 可问题是这样做的结果 还是一样 虽然是在子线程中执行了委托,委托的实例是在UI线程中创建的,但还是是在子线程中执行的,并不是说委托回调了UI中的方法就去UI线程中执行了
      

  5.   

    使用SynchronizationContext啊,参考
    通过一句SynchronizationContext.Current就可以得到UI线程的SynchronizationContext,使用静态全局变量就可以随处访问。
      

  6.   

    对啊 可问题是这样做的结果 还是一样 虽然是在子线程中执行了委托,委托的实例是在UI线程中创建的,但还是是在子线程中执行的,并不是说委托回调了UI中的方法就去UI线程中执行了
    那你可以在子线程中自定义一个事件,ui线程相应这个事件修改ui。
    我觉得你是根本没明白你的委托在干什么。也没明白什么是委托。
      

  7.   


    非常感谢。这是个好办法。但我有一个疑问。我的通讯类如A是在UI中被创建实例化的,为什么在类A的构造方法里SynchronizationContext.Current得到的是null ,只有在UI线程调用A类的实例时 SynchronizationContext.Current才有东西呢。
      

  8.   

    对啊 可问题是这样做的结果 还是一样 虽然是在子线程中执行了委托,委托的实例是在UI线程中创建的,但还是是在子线程中执行的,并不是说委托回调了UI中的方法就去UI线程中执行了
    那你可以在子线程中自定义一个事件,ui线程相应这个事件修改ui。
    我觉得你是根本没明白你的委托在干什么。也没明白什么是委托。
    我知道是在UI 线程中响应子线程中的事件,这个和控件的事件是一样的。但区别是控件的事件代码中是直接可以访问控件的,而我的子线程中的事件触发时,在UI的回调代码中只能通过控件的invoke才能访问控件。我是希望我的子线程事件和控件的事件一样,在主UI线程中直接访问控件。 楼上的yuwenge给出了一个好办法,是通过SynchronizationContext.Current 来同步线程操作让子线程也可以像invoke一样切回到主UI 上执行。但有一些些小疑问。在回复yuwenge的时候我写了。
      

  9.   

    静态变量在类实例化之前就存在了,和什么时候被实例化无关,因此你需要在UI线程的某个时刻去设置这个静态变量,一般都在UI线程的开始时候就处理的。而使用的时候也需要判断下是否为null,为null的话,说明你的对象未被UI线程接管过,或者都不在UI线程中跑,也就不需要回调。
      

  10.   


    请教下Invoke的机制,线程通过消息将委托传给它,如果委托任务完成了,是不是还要将消息回传给线程来指示任务完成的?如果线程被销毁,但是Invoke里的内容没完成,会造成卡死吗?我遇到个问题,在SerialPort的DataReceived事件里用Invoke对UI进行操作,由于串口一直有接收到数据,因此是不断的用Invoke对UI进行操作。当我将SerialPort关闭的时候(调用Close方法),会造成UI界面卡死。请问造成这种现象的原因是什么,请帮忙指点下,谢谢!
      

  11.   

    我没使用静态,还是用的实例化类来创建一个 SynchronizationContext对象。当主UI 线程调用这个类的时候 如果在UI 调用A.connect()方法,SynchronizationContext.Current 才不为NULL。 A类的构建方法和声明中SynchronizationContext.Current得到的值是NULL
      

  12.   

    本来就应该在UI线程中获取SynchronizationContext.Current来设置,你在A类的构造函数或声明中设置都是不安全的,因为你不知道A类的构造函数或声明是在哪个线程中执行的,你无法控制,你那样做就是自找麻烦。
      

  13.   

    非常感谢。看得出你是线程高手呀。呵呵
    我也试了一下,发现SynchronizationContext是在窗体控件初始化之后就不为空了。。如果写在我A类的构造代码中的确要保证构造时是在UI线程中创建的才有效。 再次感谢!~