我在做中国电信小灵通的短信开发,使用线程时遇到问题! 提交短消息,需要等网关发出submit_resp,我在用一个线程用来接收,因为我发送的消息需要网关返回的MsgID,所以我定义一个全局变里MSGID ,线程接收后马上为其赋值,在发送的那个地方有一个循环,当MsgID不等于空时,说明发送成功!但现在发送一条,或发送间隔较大的,是正确的,如果用一个循环一下子发好多,那么就是出错了,好几条短信的MSGID是一样,但实际是不一样,请问我该如何处理! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.yesky.com/SoftChannel/72342380468109312/20040523/1800310.shtml 用Hashtable来保存吧.一个线程对应一个MsgID 这个有问题啊,我现在只有一个线程,接收线程要等网关返回MSGID后才为MSGID变量赋值,先发送的短消息不一定先收到MSGID //////////但现在发送一条,或发送间隔较大的,是正确的,如果用一个循环一下子发好多,那么就是出错了,好几条短信的MSGID是一样,但实际是不一样,请问我该如何处理!/////////是不是你的哪个全局变量有问题,那几个线程都调用了同一个全局变量。 你使用同一个全局变量有问题。每收到一个都要检验一下该id的属向,表明那个信息已发送;而且每次检查到msgid后都要将其清空啊! 我估计也是全局变量的问题,因为速度太快了,但是如果我让线程sleep,那发送的效率就达不到我的要求! Response_chen(俺村俺最丑) ( ) 信誉:96 我发送并没有用线程 接收的时候我用了一个线程,为MSGID赋值,发送我用了一个while来等待接收线程,如果MSGIID不为空,那么接收线程处理MSGID,并置空! 最大的问题就是发送时要等网关下发MSGID,才结束一次submit 操作,要不然就好办了!各位有其它更好的解决方案吗?发送代码如下:byte[] bytes = submit.ToBytes(); if(bytes.Length != m_client.Send(bytes)) //发送Submit消息 { return -1; //发送失败 } while(true) //等待网关的应答结果 { if(SendOutFlag) { //RecvThread.Suspend(); MsgID = ReturnMsgID ; //ErrorMessage(MsgID); //Thread.Sleep(10); //RecvThread.Resume(); SendOutFlag = false ; return SubmitRes; } //RecvThread.Resume(); long temp = DateTime.Now.Ticks - tBegin; if((DateTime.Now.Ticks - tBegin) > OutTime) //判断超时 > 15秒 { ErrorMessage("等待网关应答结果超时"); return -1; } }接收线程中的代码:SendOutFlag = false ; if (msgheader.RequestID == SMGP_COMMAND_ID.SMGP_SUBMIT_RESP) //处理submit_resp消息 { try { SMGP_SUBMIT_RESP submit_resp = new SMGP_SUBMIT_RESP(resp_data); if (submit_resp.Header.RequestID == SMGP_COMMAND_ID.SMGP_SUBMIT_RESP) { ReturnMsgID = submit_resp.MsgID ; SubmitRes = Convert.ToInt32(submit_resp.Status) ; SendOutFlag = true ; //Thread.Sleep(50); ErrorMessage(submit_resp.MsgID+" "+i.ToString()); i++; index += (int)msgheader.PacketLength; //设置索引 //RecvThread.Abort(); } } catch { //return -1 ; } 用事件激发可参考http://blog.csdn.net/cntoweiyelee/archive/2004/12/02/202191.aspx 事件激发没法用啊,我要等MSGID呢,再说网关下发的短消息我就是用事件激发的,那就好解决?运行稳定且正常! ErrorMessage(submit_resp.MsgID+" "+i.ToString());其实这一句就是事件激发的!呵呵 另外,你为什么要手动设置和控制线程呢?我觉得像这样的应用,用ManualResetEvent之类的自动控制线程的进行和阻塞会比较好。 可能是一个线程运行时,其他线程篡改了变量,你在那个改变量的地方把变量给lock一下,应该可以解决。lock(msgid){...} 楼主你好可以知道你的submit包结构怎么写的吗,谢谢了! 参照协议啊!告诉你一个CMPP协议实现的C#代码的例子!http://www.cnblogs.com/microshaoft/archive/2005/03/18/121005.html 程序涉及到2个线程,主程序发送线程,接收线程,问题主要是对临界变量的访问,对于这些变量的访问,我一般是封装成单独的对象,通过setvalue,getvalue通用的函数访问,这些函数上加lock限制,这样更清晰些,从来没出过错。对于发送多条短信,感觉是用queue更好些。 squin(*squin*) 能否给一点参考代码!谢谢 while(true) //等待网关的应答结果就在这里容易挂死。 while(true) //等待网关的应答结果就在这里容易挂死。是啊,等高手出现帮忙! 有可能是缓冲没有清除掉,试一下每次定义新的SGID,或者每次初始化有关的进程或句柄 其实搂主已经发现了问题的所在,就是让主线程sleep一段时间可能没问题,你的while是由主线程来控制的,如果主线程不sleep,就是由系统来给两个线程分配时间片,这样并不是间隔的平均分配(我测试过),再加上msgid是个全局变量,出现楼主所述现象是必然的。你的msgid应该封装在一个类里面,发送时实例化,并且在get或set时用lock。 将属于该数据集中的表移到该数据集中的方法 做了个自动更新程序,如何覆盖自己? dataGridView删除数据行(在线等待) 怎么在logout以后,使session失效 DXperience 控件 分发问题 XBAP可以与网页交互吗? C#调用C++的DLL,异常System.DllNotFoundException 如何在Pocket PC上使用自定义控件,急,在线等! 水晶报表 主从表设计问题? jmail收取邮件 中文乱码 关于在已绑定数据的DataGrid中添加对应Radio控件的问题 关于win form制作安装文件的问题,桌面和开始-程序菜单中的快捷方式不能够运行程序(40)
一个线程对应一个MsgID
但现在发送一条,或发送间隔较大的,是正确的,如果用一个循环一下子发好多,那么就是出错了,好几条短信的MSGID是一样,但实际是不一样,请问我该如何处理!/////////是不是你的哪个全局变量有问题,那几个线程都调用了同一个全局变量。
每收到一个都要检验一下该id的属向,表明那个信息已发送;而且每次检查到msgid后都要将其清空啊!
我发送并没有用线程
发送代码如下:
byte[] bytes = submit.ToBytes();
if(bytes.Length != m_client.Send(bytes)) //发送Submit消息
{
return -1; //发送失败
}
while(true) //等待网关的应答结果
{
if(SendOutFlag)
{
//RecvThread.Suspend();
MsgID = ReturnMsgID ;
//ErrorMessage(MsgID);
//Thread.Sleep(10); //RecvThread.Resume();
SendOutFlag = false ;
return SubmitRes;
}
//RecvThread.Resume();
long temp = DateTime.Now.Ticks - tBegin;
if((DateTime.Now.Ticks - tBegin) > OutTime) //判断超时 > 15秒
{
ErrorMessage("等待网关应答结果超时");
return -1;
}
}接收线程中的代码:SendOutFlag = false ;
if (msgheader.RequestID == SMGP_COMMAND_ID.SMGP_SUBMIT_RESP) //处理submit_resp消息
{
try
{
SMGP_SUBMIT_RESP submit_resp = new SMGP_SUBMIT_RESP(resp_data);
if (submit_resp.Header.RequestID == SMGP_COMMAND_ID.SMGP_SUBMIT_RESP)
{
ReturnMsgID = submit_resp.MsgID ;
SubmitRes = Convert.ToInt32(submit_resp.Status) ;
SendOutFlag = true ;
//Thread.Sleep(50);
ErrorMessage(submit_resp.MsgID+" "+i.ToString());
i++;
index += (int)msgheader.PacketLength; //设置索引
//RecvThread.Abort();
}
}
catch
{
//return -1 ;
}
可参考http://blog.csdn.net/cntoweiyelee/archive/2004/12/02/202191.aspx
其实这一句就是事件激发的!呵呵
{
...
}
告诉你一个CMPP协议实现的C#代码的例子!
http://www.cnblogs.com/microshaoft/archive/2005/03/18/121005.html
的访问,我一般是封装成单独的对象,通过setvalue,getvalue通用的函数访问,这些函数上
加lock限制,这样更清晰些,从来没出过错。对于发送多条短信,感觉是用queue更好些。
能否给一点参考代码!谢谢
是啊,等高手出现帮忙!