利用UdpClient.Receive方法接收到数据后,弹出一个新的窗体,必须得是form.Show()出来的窗体,结果这个新出来后就不动了,这个线程死在这里了。我估计是国为UdpClient.Receive方法是阻塞方式,所以才会这样,可我搞了好久也没找到解决办法,利用异步处理也没成功,不知是我写的不对还是根本不行,请大家一起找找解决办法。
解决方案 »
- 验证码识别--经验交流-------去除背景色---------------------
- 自动创建一个Table,如何设置某个单元格中的Text居中对齐。
- 我是个笨蛋求教用VS2008 C#做个系统登录界面做好了怎么链接到菜单
- WinForm如何设置个统一设置 代码怎么写啊
- 刚才和同事争论关于变量的问题的问题
- 如何在SQL语句中使用循环和数组
- 高手请进
- 如何用C#获取当前运行的应用程序列表及窗口的句柄 而不是当前进程列表
- 急问一个很多人都遇到过的问题
- WindowsXP支不支持 .NET Frame?
- 如何把stream文件流转化为文件?
- Response.Write(Session["SS_MENUID"].ToString());
private void StartListener()
{
Thread.Sleep(2000);
RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, GroupPort);
while(true)
{
try
{
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); string returnData = Encoding.UTF8.GetString(receiveBytes); Form2 myForm=new Form2();
myForm.Show();
Application.DoEvents();
//到这里,新窗体出来后就死在那里,一关,整个程序都关了
}
catch
{
}
}
}
LZ的模型错了。当你在接受线程show()新窗口后再次回到while(true)去执行阻塞的Recieve()动作。而你Show()出来的Form是[STA]的,也就是强制单线程。这就意味着该Form的消息泵是在你的接受线程运行的。由于该线程被Recieve()阻塞了,所以新Form无法作消息循环,当然没响应。合理的做法是当接受线程受到udp包时通过委托机制通知UI主线程,需要的话将接受到的内容一并发送给UI线程。然后由UI线程负责new Form。整个模型的关键在于线程通信
还有你Form2.Show()是干吗的,不会显示一个空窗体吧,我想在你的Form2 的load或者其它事件里还有处理语句,检查一下看看呐
你应该是讲到点子上了,可我对线程间的通讯却不清楚,能否就你上述所说的给个简单的例子?
ms-help://MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondevelopingmultithreadedwindowsformscontrol.htm如果你需要一般的多线程通讯,可以去搜索“实现IAsynchronizeInvoke接口”,有关代码我自己也没仔细看,不敢乱发
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Text;namespace EasyUdp
{
/// <summary>
/// 用作onRecv事件的参数的类
/// </summary>
/// <permission cref="EasyUdp">Public Class</permission>
public class EasyUdpRecvCtlEventArgs //: EventArgs
{
/// <summary>
/// 包含发送Udp数据报的远端主机的IP
/// </summary>
/// <permission cref="EasyUdp.EasyRecvCtlEventArgs">Private Member</permission>
private string remoteIP; public string RemoteIP
{
get
{
return this.remoteIP;
}
}
private string recvStr;
public string RecvStr
{
get
{
return this.recvStr;
}
} /// <summary>
/// EasyUdpRecvCtlEventArgs的构造函数
/// </summary>
/// <param name="remoteIP">发送Udp数据报的远端主机的IP</param>
/// <param name="recvStr">接收到的字符串</param>
public EasyUdpRecvCtlEventArgs(string remoteIP,string recvStr)
{
this.recvStr = recvStr;
this.remoteIP = remoteIP;
} } /// <summary>
/// UserControl1 的摘要说明。
/// </summary>
public class EasyUdpRecvCtl : System.Windows.Forms.Control
{
//private EventHandler onRecvHandler; //public event EventHandler onRecv; public delegate void OnRecvHandler(object Sender,EasyUdpRecvCtlEventArgs e);
private OnRecvHandler onRecvHandler; public event OnRecvHandler onRecv; private UdpClient udpReceiver; private Thread hearkenThread; private byte[] recvBytes = new byte[500];
private string recvStr; private Encoding encoder = Encoding.Unicode;
private int localPort;
public int LocalPort
{
get
{
return localPort;
}
set
{
localPort = value;
}
}
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null; public EasyUdpRecvCtl(int local_Port)
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent(); //初始化UdpReceiver将其绑定到localPort端口
this.localPort = local_Port;
if(this.DesignMode == false)
{
try
{
this.udpReceiver = new UdpClient(this.localPort);
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
throw new Exception("端口已被占用!");
}
}
// TODO: 在 InitComponent 调用后添加任何初始化
this.onRecvHandler = new OnRecvHandler(OnRecv);
} public EasyUdpRecvCtl()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent(); //初始化UdpReceiver将其绑定到localPort端口
if(this.DesignMode == false)
{
this.localPort = 10000;
try
{
this.udpReceiver = new UdpClient(this.localPort);
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
} // TODO: 在 InitComponent 调用后添加任何初始化
this.onRecvHandler = new OnRecvHandler(OnRecv);
} /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing ); //关闭udpReceiver
//this.udpReceiver.Close();
} #region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated (e); //初始化侦听线程开始侦听
this.hearkenThread = new Thread(new ThreadStart(HearkenProc));
this.hearkenThread.Start(); } protected override void OnHandleDestroyed(EventArgs e)
{
//销毁侦听线程
this.hearkenThread.Abort();
//this.hearkenThread.Join();
//关闭udpReceiver
this.udpReceiver.Close(); base.OnHandleDestroyed (e);
} private void OnRecv(object Sender,EasyUdpRecvCtlEventArgs e)
{
this.onRecv(Sender,e);
} private void HearkenProc()
{
//只侦听对方10001端口发到本机的Udp包
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any,10001); while(true)
{
this.recvBytes = this.udpReceiver.Receive(ref remoteIPEndPoint);
this.recvStr = this.encoder.GetString(recvBytes); //收到数据报后跨线程(向控件主线程)激发事件onRecvHandler
//将收到的数据和对方IP发回主线程
this.BeginInvoke(this.onRecvHandler,
new object[]{
this,
new EasyUdpRecvCtlEventArgs(remoteIPEndPoint.Address.ToString(),recvStr)
});
}
}
}
}