在刚刚完成的项目中遇到了些问题,化了很长的时间处理,都没有效果,但“有心栽花花不开,无心插柳柳成荫”,特总结下经验,同时谢谢提供无私帮助的redbb,lxcc,saucer等。
一个通讯的项目,一个winform托盘,一个windows service.
winform启动service,同时返回windows service的数据。
windows service负责与两台服务器通讯,并做逻辑处理。
问题一:线程
调试windows service可运行,不是调试状态就不运行
protected override void OnStart(string[] args)
{
Process CommProcess = Process.GetCurrentProcess();
CommProcess.PriorityClass=ProcessPriorityClass.RealTime;
XCOM_instance.clsXCOMComm_Start();
VIP_instance = new clsVIPComm();
}
其中
public void clsXCOMComm_Start()
{
thread_heart.Start();
thread_receive.Start();
thread_send.Start();
}
构照函数
public clsVIPComm()
{
Msg_Length = TCP_Msg_Length;
Initial.setds();
VIPComm_Start();
}
public void VIPComm_Start()
{
thread_send.Start();
thread_receive.Start();
}
线程几乎相同,就简单举个例子
Thread thread_receive = new Thread(new ThreadStart(TCPAsyncComm.receive));
public static void receive()
{
try
{
if (!sClient.Connected)
{
sClient.BeginConnect(new IPEndPoint(IPAddress.Parse("192.16.10.1"), 5001),new AsyncCallback(ConnectCallback),sClient);
socketEvent.WaitOne();
}
sClient.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),sClient);
socketEvent.WaitOne();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
socketEvent.Set();
return;
}
}
分析:在receive处添加了断点,不明白为什么调试可以到达断点,而不加调试就到不了,显示的信息是线程中断。调试windows service是麻烦的事情,看以前的Console程序是可以运行的,又把windows service换到了winform,线程中断了,难道Console和winform结果还不一样吗?
解决:
protected override void OnStart(string[] args)
{
Process CommProcess = Process.GetCurrentProcess();
CommProcess.PriorityClass=ProcessPriorityClass.RealTime;
XCOM_instance.clsXCOMComm_Start();
VIP_instance = new clsVIPComm();
Console.ReadLine(); //就是这里
}
线程中断的原因就是上面那里,其实总觉得在windows service中Console和winform的东西都没有显示啊,应该没有什么用,却不知道问题就在这里啊!调了两个小时。
问题二:丢包
因为是和一个PLC(可编程逻辑控制器)通讯,在我看过的socket例子中,send函数中都要加上Thread.Sleep(100);因为不停一下,那相邻发送的两个信息就会合到一个包里,我做过测试,如果这个Sleep小于50,就会出现这种情况,那个PLC不知道怎么做的,通讯板发出的信号好像没有延迟,一次发8-10个,我收到的时候总会或多或少的丢失,约3%(特地做了个监控程序)。
分析:因为与之通讯的不是服务器或PC,没有办法调整参数,接收方面已经做异步委托处理了
public static void ReceiveCallback(IAsyncResult ar)
{
try
{
Socket sClient = (Socket)ar.AsyncState;
int bytesRead = sClient.EndReceive(ar);//,i=0;
if (bytesRead>0)
{
DelegateReceive delegatereceive = new DelegateReceive();
delegatereceive.receiveBytes = buffer;
Thread delegatereceivethread = new Thread(new ThreadStart(delegatereceive.DecodeMethod));
delegatereceivethread.Start();
sClient.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),sClient);
}
else
{
Debug.WriteLine("=======Finished==========");
socketEvent.Set();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
socketEvent.Set();
}
}
不可能再优化了,此段程序耽误了大量时间,约2周。
解决:突一日,想起还没有做Release版,于是把Debug版换到R版,奇怪的现象出现了,数据没有丢失了,唉!这简单的一换,可......由此可见,R版效率比D版高,差点逼得我加CPU了。
问题三:响应
项目需要ms级反映,速度相当快,比如10ms送10个包,1s就是1000个包,windows service接收到后还要显示到外面托盘的winform上,两个应用程序域可以用remoting实现,我用的是UDP,道理是一样的,显示是通过datagrid实现的,在datagrid中加一列value,有一个ComboBox,选择哪个信号就显示哪个信号的值。程序几乎无法运行,只能运行几秒种,CPU利用率出奇的高,不用winform,直接在service中启动服务,CPU利用率5%。
分析:看样子是winform中的datagrid显示导致了CPU利用率的升高
解决:优化winform中的显示,只显示很少的东西,双击看细节,结果在100ms的时候利用率不超过20%,10ms太快了,CPU 80%,本实现了需求,看来把东西做到后台优势是很明显的,另外就是太频繁的显示不要做到winform上,windows可视化是好,但对资源的消耗也非常大。
抛砖引玉了。
---------------------------------------------------------------
分真多
流口水了
---------------------------------------------------------------
GZ,今天没回家。
---------------------------------------------------------------
牛!
---------------------------------------------------------------
学习
---------------------------------------------------------------
學習中...
---------------------------------------------------------------
牛xxx
学习一下,刚接触socket !
---------------------------------------------------------------
收~~!
---------------------------------------------------------------
存!
---------------------------------------------------------------
太惭愧了!没帮上什么!
---------------------------------------------------------------
正好我也关注.项目需要. 哎.
---------------------------------------------------------------
收藏学习,感谢:_)
---------------------------------------------------------------
学习先
---------------------------------------------------------------
有些经验值得借鉴,不过太多的异步处理会导致程序跑的更慢。因为异步处理总是使用系统线程池。
---------------------------------------------------------------
学习学习
---------------------------------------------------------------
好东西,经验之谈!!值得收藏!!
---------------------------------------------------------------
牛人,我喜欢
---------------------------------------------------------------
收藏了好好看
---------------------------------------------------------------
....只能说学习了
---------------------------------------------------------------
学习中
---------------------------------------------------------------
需要,学习,mark.
---------------------------------------------------------------
收藏
---------------------------------------------------------------
好东西,学习,再学习
up
---------------------------------------------------------------
真正的高手,收藏,我真要开发一个socket服务端,用windows service可以吗?希望楼主解释一下
---------------------------------------------------------------
学习.
---------------------------------------------------------------
接分。
---------------------------------------------------------------
好,收藏,
谢
---------------------------------------------------------------
好,收藏
---------------------------------------------------------------
加入收藏了。
谢谢你的经验:)
---------------------------------------------------------------
强人啊
---------------------------------------------------------------
好,互相学习
---------------------------------------------------------------
学习
---------------------------------------------------------------
SOCKET太复杂了,学习中,顶,
---------------------------------------------------------------
收藏:)
---------------------------------------------------------------
厉害
---------------------------------------------------------------
up
---------------------------------------------------------------
希望楼主告知怎样在线程中通信,谢谢。我要向ui线程发送消息,以显示进度,该如何办?参数怎么传?
---------------------------------------------------------------
好文章,感谢楼主了。
顺便接点分!
---------------------------------------------------------------
学习
---------------------------------------------------------------
学习
---------------------------------------------------------------
学习,谢谢
---------------------------------------------------------------
mark
---------------------------------------------------------------
好想楼主再多说点,可以多学点
------------------------------------------------------------