奋战了几天,类似QQ的多客户端私聊程序已经基本成功了。但是存在一个另我非常烦恼的问题:
    我的程序的基本执行流程如下:我把问题一分为二,第一部分实现客户端向上一及的服务器发送消息(调用远程对象中的一个函数),该函数触发服务器端接受到客户端消息事件;第二部分实现,当触发服务器端接受到客户端消息事件后,又触发向目标客户端专发该消息事件,该事件包含目标客户端接受和显示该信息的几个函数代理。这样最终消息就经服务器成功地送到了目标客户端。
    
    我已经做了测试:事件的传递触发逻辑和流程都没问题,消息字符串的传递也没问题。问题就在第二部分中的显示信息一步。我是用textbox来显示新到的信息的:
                  tb_show.Text += System.Environment.NewLine+msg;
看着没问题,但是确出错了,原先在调试时有错误提示,大概意思就是说,无法切入到该界面空件的操作。后来干脆没提示,抓异常提示一些没用的。
    我个人的诊断:因为执行界面内容更新的函数的代理是被赋值给远程对象中的事件的处理器中的,所以它是被远程对象触发而执行的,也许可以说这个一个独立的进程,而执行tb_show.Text += System.Environment.NewLine+msg语句,该进程希望直接切入到客户端的进程中,自然不行。
    不只我的理解正确否,还请各位指点,我将该显示更新语句改成:
     messagebox.show(msg);
能收到真确的信息,整个系统运行也没问题。我想问题就出在那了。

解决方案 »

  1.   

    因为回调其实是多线程。所以要用Invoke+delegate来改变控件属性,直接改变是不行的。看看我的文章吧。
      

  2.   

    哈哈,和我以前遇到的问题一样啊,好好看看Controls.invoke()这个方法吧
      

  3.   

    c# & asp.net讨论群:32095860  欢迎有开发经验的朋友加入
      

  4.   

    如果是要在线程中为控件赋值可以在构造函数中加上CheckForIllegalCrossThreadCalls = false;这句(以2003的进程管理方式运行)
      

  5.   

    CheckForIllegalCrossThreadCalls设为false 只是不会报错,并不代表没有问题。
      

  6.   

    问题已经解决了,我已经给完分了。我肯定两位说的是对的,但我又另外发现用这个方法( MethodInvoker mi = new MethodInvoker(show_msg)创建代理,BeginInvoke(mi)执行)也可以,也挺简单的。
    代码如下:
     public void receive_msg(string msg)
            {
                //MessageBox.Show(msg);
                //tb_show.Text += System.Environment.NewLine+msg;
                MethodInvoker mi = new MethodInvoker(show_msg);
                received_string = msg;
                BeginInvoke(mi);
            }
            //进程中指定的委托制向的方法
            public void show_msg()
            {
                tb_show.Text += System.Environment.NewLine + received_string;
            }