本帖最后由 wsptr 于 2010-03-20 00:09:09 编辑

解决方案 »

  1.   

    private void dataReceiver_DataReceived(object sender,EventArgs e)
    {
        textBox1.Text=textBox1.Text+"ABCDE\r\n";    //注意,这一行改为使用委托更新界面效果一样。
        MessageBox.Show("Data Received!");
    }    textBox1.Text=textBox1.Text+"ABCDE\r\n";    注意,这一行改为使用委托,并且要使用异步调用BeginInvoek,不要同步进行调用.
      

  2.   

    对CE完全不了解。
    之所以这么问是因为有时候单独开的线程如果抛出异常, 
    在vista里面是悄悄给隐藏起来不显示的。
    我也不知道为什么。有的时候能碰到有的时候又不出现。我觉得不用BeginInvoke, 如果系统是XP, 是会报一个InvalidOperationException的。
    而又因为是单独开的线程, 异常被吃掉了。
    所以毫无反应。不过CE我就不知道会不会有一样的问题了。
      

  3.   

    呃,你说的“单独开的线程”是指DataReceiver组件吧?
    组件中是有一个UDP的线程,但在组件的事件中是没有独立的线程的,就是触发事件后更改界面而已。这个组件类似SerialPort组件,我上面代码里的 dataReceiver_DataReceived 事件是在另一个项目中的,另一个项目使用了DataReceiver组件,不是和DataReceiver在一起的。问题发生在使用DataReceiver组件的工程中。
      

  4.   

    只通过你贴的这些代码看
    我感觉你的事件是挂在了OnDataReceived上面。
    而OnDataReceived是在Start里面处理的
    Start又在thdReceive线程里面。
    所以跨线程操作控件了。所以我才怀疑了下会不会有异常。
      

  5.   

    OnDataReceived()只抛出这个事件而已啊,里面只有一句话。
    如果是挂在OnDataReceived上面,那怎么还会在使用组件的窗体上触发事件呢?所以我觉得不应该是这个原因……
      

  6.   

    这个组件确实类似SerialPort组件,你如果用过SerialPort组件,OnDataReceived触发的事件是在你新建的线程里执行的,所以是跨线程更新界面了,需要使用委托.
    你可以通过 分别在OnDataReceived方法和主窗体中调用  Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString);来比较就可以确定它们是否属于同一个线程了.另外你在SerialPort组件中调用委托的同步方法去更新界面就有可能会发生死锁,具体原因倒是没研究清楚,不过在改用异步调用之后就正常了.
      

  7.   

    你的问题应该是工作线程如何更新UI线程中的对象。UI线程(主线程)中的UI对象是不能被其他线程直接使用的,这个是违反安全性原则的,必须使用通知的机制。
      

  8.   

    补充一句,如果删掉
    textBox1.Text=textBox1.Text+"ABCDE\r\n";
    的话,程序是正常跑的,这一句换成委托也跑不了,进到委托里执行这一句时同样阻塞住了。
      

  9.   

    跨线程更新UI的问题。再建个委托,把更新的代码放委托的函数里。rivate void dataReceiver_DataReceived(object sender,EventArgs e)
    {
    this.Invoke();//传你的委托进去。如果Form上没有invoke方法,就把this换成textbox1
    }