积极答复者
在异步通信时如何临时阻止主线程运行?

问题
-
尝试搞了一个用TcpClient异步接收发送的东西,在发送的时候碰到一些问题,主线程刷数据刷得太快了,就是for循环那里,结果是前面的还没发完,后面的旧接着刷上去了,在非调试下另一边的接收方只能接到前面2-3条,后面的都没有,当在BeginWrite处设立断点一条一条来按时,对面就能全部接收到,据说用ManualResetEvent的WaitOne 可以在发送时先临时阻止主线程 For 循环的执行,之后再用 Reset 使其继续 ,在 SendData 一开始就 WaitOne ,然后在 SendCallBack 最后 Reset ,但运行起来完全没有效果,这个应该怎么弄?
定义有
private NetworkStream ns;
private struct msgstruct
{
public string msg;
public string st;
}
protected ArrayList SendArrList = new ArrayList(); //用来装msgstruct 的
点击按钮触发
for (int isend = 0; isend < SendArrList.Count; isend++)
{
msgstruct sendstruct = (msgstruct )SendArrList[isend]; //sendstruct 是一个结构,里面是发送的信息msg 和执行的策略st,
string revder = sendstruct.msg;
string sdate = sendstruct.st;
SendData(“sa”, sendstruct.msg, sendstruct.st);
}private void SendData(string rever,string msg,string lvl) //发送
{
byte[] reverbit = reverbit.GetBytes(rever);
byte[] msgrbit = msgbit.GetBytes(msg);
byte[] lvlbit = lvlbit.GetBytes(lvl);
MemoryStream mem = new MemoryStream();
mem.Write(reverbit , 0, reverbit.Length);
mem.Write(msgrbit , 0, msgrbit.Length);
mem.Write(lvlbit , 0, lvlbit.Length);
byte[] msgbody = mem.ToArray();
ns.BeginWrite(msgbody , 0, msgbody.Length, new AsyncCallback(SendCallBack), ns); //设置断点位置
ns.Flush();
}
private void SendCallBack(IAsyncResult iar)
{
try
{
ns.EndWrite(iar);
}
catch (Exception e)
{
}
}- 已移动 Sheng Jiang 蒋晟Moderator 2009年7月6日 17:23 软件设计问题 (发件人:Visual C#)
- 已移动 Sheng Jiang 蒋晟Moderator 2009年7月6日 17:23 软件设计问题 (发件人:Visual C#)
答案
-
正常的办法是把所有要发的东西放在队列里 把队列作为参数 放在同步状态的 sync object中
在不断的 endsend 线程中 从同步状态中的队列取出下一个内容 再次begingsend 这样就可以高效率的循环了
紫柔版主的头像真叫萌得一个不行啊。。。。
答案800 撒花- 已建议为答案 肖小勇Moderator 2009年7月6日 9:21
- 已标记为答案 韦恩卑鄙 waywaModerator 2009年7月8日 6:53
全部回复
-
我也有遇到过类似的问题。我的解决方式是:状态位+Thread.Sleep;思路为:bool _Complete=false;for(...){...while(!_Complete){System.Thread.Sleep(400); _Complete=false;}}private void SendCallBack(IAsyncResult iar)
{
try
{
ns.EndWrite(iar);
_Complete=true;
}
catch (Exception e)
{
}
}这个方式 比较 简单,而且通过 修改 不同的 Sleep时间,可以提高 程序 的响应时间! Sleep 时间 的确认,您可以 使用 10/CPU频率*100 公式来获得 ms 优化值
虫子(Tech-Worm:270816377) -
正常的办法是把所有要发的东西放在队列里 把队列作为参数 放在同步状态的 sync object中
在不断的 endsend 线程中 从同步状态中的队列取出下一个内容 再次begingsend 这样就可以高效率的循环了
紫柔版主的头像真叫萌得一个不行啊。。。。
答案800 撒花- 已建议为答案 肖小勇Moderator 2009年7月6日 9:21
- 已标记为答案 韦恩卑鄙 waywaModerator 2009年7月8日 6:53
-
我也有遇到过类似的问题。
我的解决方式是:状态位+Thread.Sleep;思路为:bool _Complete=false;for(...){...while(!_Complete){System.Thread.Sleep(400); _Complete=false;}}private void SendCallBack(IAsyncResult iar)
{
try
{
ns.EndWrite(iar);
_Complete=true;
}
catch (Exception e)
{
}
}这个方式 比较 简单,而且通过 修改 不同的 Sleep时间,可以提高 程序 的响应时间! Sleep 时间 的确认,您可以 使用 10/CPU频率*100 公式来获得 ms 优化值
虫子(Tech-Worm:270816377)
这样做会不会导致界面卡住动不了? System.Thead 停掉的范围是整个程序还是后台?