最近在写一个TCP通信程序,自定义了一个通信类TCPclient,用于客户端异步接收和发送网络消息。

TCPclient中定义了一个接收到新的网络消息事件:

  //收到新消息事件
public delegate void receiveNewNetworkMsgHandler( string networkMSG);
public event receiveNewNetworkMsgHandler receiveNewNetworkMsg;

在外部的窗体中订阅了此事件:

void thisClient_receiveNewNetworkMsg( string networkMSG);

起初是直接在这个函数中读取网络消息,并解析命令,然后触发窗体的LoginSuccess事件,LoginSuccess事件的委托函数会New一个 main 窗体

但是问题是这个new的main窗体总是无响应。

经过很长时间的摸索,终于得出以下结论

在自定义类中定义并触发事件,那么UI中的事件处理代码也就工作在自定义类线程中,访问UI中控件需要invoke
在此之前,我一直认为事件处理函数在哪个类,自然运行的时候就在相应的线程中执行,至此才明白错在哪里。

根据这条结论,自然就不能直接在thisClient_receiveNewNetworkMsg函数中直接进行命令的解析以及触发LoginSuccess事件,

所以现在在thisClient_receiveNewNetworkMsg函数中进行如下更改:

         public delegate void NetMsgDealHandler(string str);
void thisClient_receiveNewNetworkMsg( string networkMSG)
{
NetMsgDealHandler newMSG = new NetMsgDealHandler(NetMsgDeal);
BeginInvoke(newMSG, networkMSG);
}
         void NetMsgDeal(string networkMSG) {
XmlDocument xmldoc = new XmlDocument();
try { xmldoc.LoadXml(networkMSG); }
catch (Exception ex) { MessageBox.Show(string.Format("XML加载错误({1}):{0}", networkMSG, ex.Message)); return; }
XmlElement rootElement = xmldoc.ChildNodes[] as XmlElement;
XmlElement SecElement = rootElement.ChildNodes[] as XmlElement;
switch (SecElement.Name) {
case "login": {
if (SecElement.SelectSingleNode("cmd").InnerText == "") {
if (SecElement.SelectSingleNode("isSuccess").InnerText == "True") {
//触发LoginSuccess事件
this.loginSuccess(this);
}
else {
//触发loginFailed事件
this.LoginFailed(this);
}
}
} break; //此处省略若干行
default: { MessageBox.Show(string.Format("得到无法处理的消息:{0}", networkMSG)); return; }
}
}

现在再次执行main窗体不在无响应,问题成功解决!

C#多线程与UI响应 跨线程更新UI的更多相关文章

  1. (转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例

    http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-dem ...

  2. C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)

    概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. ...

  3. 简短总结一下C#里跨线程更新UI(转)

    摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...

  4. 简短总结一下C#里跨线程更新UI

    摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...

  5. Winform之跨线程更新UI

    Winform之跨线程更新UI 使用`Invoke`或者`BeginInvoke`与UI线程交互示例 参考及源码 使用Invoke或者BeginInvoke与UI线程交互示例 private void ...

  6. C# Winform 跨线程更新UI控件常用方法总结(转)

    出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...

  7. C# 跨线程更新 UI

    Winforms 跨线程更新 UI 在 Winforms 中, 所有的控件都包含 InvokeRequired 属性, 如果我们要更新UI,通过它我们可以判断是否需要调用 [Begin]Invoke. ...

  8. C# WinForms跨线程更新 UI

    与在Android中一样, 子线程中更新UI被认为是线程不安全的, 会抛出异常. 子线程返回UI线程中更新UI的一个方法为: 1, 捕获应用的UI线程的上下文; 2, 定义线程任务; 3, 定义线程任 ...

  9. C#利用委托跨线程更新UI数据

    转:http://www.2cto.com/kf/201206/136587.html 在使用C#的过程中,难免会用到多线程,而用多线程之后,线程如何与界面交互则是一个非常头疼的问题.其实不仅仅是界面 ...

随机推荐

  1. 如何删除Weblogic域

    1. delete entry in WL_HOME/common/nodemanager/nodemanager.domains 2. delete entry in FMW_HOME/domain ...

  2. ArcEngine实现捕捉节点

    来自:http://blog.sina.com.cn/s/blog_4d0b75870100o960.html //获取最近的结点,然后在  OnMouseMove中显示 //pnt:鼠标移动点 // ...

  3. CGFloat、CGPoint、CGSize和CGRect

    CGFloat:是表示浮点数类型. CGPoint:表示二维坐标的点.通过x和y坐标定义.点表示位置值. CGSIZE:表示矩形的宽度和高度.通过宽度和高度来定义. CGRect: 表示矩形的位置和大 ...

  4. OC之Block的用法和实现委托

    Block的基本概念 Block的基本用法 Block实现委托机制 一.Block的基本概念 Block是程序的代码块,这个代码块可以在需要的时候执行.IOS开发中,block到处可见,所以学好很重要 ...

  5. TinyThread源码分析之中断

    转载请注明来源:cuixiaolei的技术博客 https://github.com/xhawk18/TinyThread TinyThread 是基于Cortex-M0的小型的OS. 知识储备: I ...

  6. Qt绘图控件qwt绘制等比例坐标图

    需要用到QwtPlotRescaler类,用法如下: QwtPlotRescaler *plotRescaler = new QwtPlotRescaler(canvas, yLeft, QwtPlo ...

  7. JavaScript 键盘event.keyCode值列表大全

      JavaScript 键盘event.keyCode值列表大全   event.keyCode值列表大全,对于需要根据键盘按键触发相应事件的朋友需要. 网上收集的KeyCode值方便大家查找: k ...

  8. 浅议tomcat与classloader

    关于tomcat和classloader的文章,网上多如牛毛,且互相转载,所以大多数搜到的基本上是讲到了tomcat中classloader的几个层次,对于初接触classloader,看了之后还是只 ...

  9. MyFragment

    手机横竖屏自动切换不同的View: Landscape-Horizontal-横屏 Portrait-Vertical-竖屏 package com.example.shad_fnst.myfragm ...

  10. 【Cocos2d入门教程三】HelloWorld之一目了然

    什么程序都是从HelloWorld先开始.同样Cocos2d-x我们先从HelloWorld进行下手.下面是HelloWorld的运行完成图: 建立好的Cocos游戏项目中会有两个比较常用接触的文件夹 ...