问题描述
同步加线程使用事件并发处理接收到的数据publicvoidSyncRecive(){Tasklisten=newTask(()=>{while(true){intlength=connect.ReceiveFrom(this.packetBuffer,0,this.packetBuffer.Length,SocketFlags.None,refthis.remoteEndPoint);byte[]packet=this.packetBuffer.Unpack(length);if(length!=active.Length||packet.ToMessage()!=active.ToMessage()){this.counter++;if(this.ReceiveData!=null){this.ReceiveData(packet,this.remoteEndPoint,null);}}}});listen.Start();}异步publicvoidAsynRecive(){connect.BeginReceiveFrom(this.packetBuffer,0,this.packetBuffer.Length,SocketFlags.None,refthis.remoteEndPoint,newAsyncCallback(AsynReciveCallback),null);}privatevoidAsynReciveCallback(IAsyncResultasyncResult){if(asyncResult.IsCompleted){intlength=connect.EndReceiveFrom(asyncResult,refthis.remoteEndPoint);byte[]packet=this.packetBuffer.Unpack(length);this.counter++;if(this.ReceiveData!=null){this.ReceiveData(packet,this.remoteEndPoint,null);}}this.AsynRecive();}同步加线程接收效率明显高于异步这样的情况下使用异步还有优势吗?
解决方案
解决方案二:
同步线程模式完全没有IAsyncResult对象的问题是这个原因速度提高了吗
解决方案三:
我不知道你所谓的效率更高是如何得出的结论如果你是说单纯从某一次访问(只有一个客户端进行访问),同步响应速度更快的话,这说明不了什么的还是拿我经常举的例子来说:假如你是等快递,你自己站门口等当然比门卫收到快递给你打电话会更快那么一点点,但是这只是你一个人的情况如果有100个客户端去访问你的服务端,好比有100个人要收快递,你不可能让100个人都跑到门卫去排队等吧?
解决方案四:
如果是10000个人要收快递呢?很明显只让一个人在那里等,来了谁的快递就给谁打电话来取,单纯从某一个人来说,可能不如他自己在那里等更快,但是总体上来说,更节约资源,也能够响应更多的请求,而不至于超过10个人就把门卫塞满了
解决方案五:
你说的这个我明白TCP(会出现你说的100个人要收快递,UDP不会吧无连接)肯定是异步好因为并发N个连接我这样做就要有多少连接就开多少线程(线程下还要并发事件)UDP接收的时候就是对一个端口死循环接收不存在连接(虽然也可以建立连接可连接以后就变1对1了)同步接收是这样的来了快递---->个人站门口(并发事件N个人站这个人后面)---->>>循环异步来了快递---->电话(IAsyncResult)------>收快递(并发事件N个人站这个人后面)---->>>循环
解决方案六:
UDP其实也差不多的虽然是面向无连接的,那么同步就是派一个人在那等,等到了他就拿着快递给别人送去,送完再回去等而异步就是让门卫等,来了快递给别人打电话,别人接到电话再自己来取可能差别并不像TCP通信那么大包括客户端TCP通信,用同步还是异步差别也并不大,而且异步反而不容易控制逻辑顺序
解决方案七:
我做的是事件模式,一个人收到快递后会触发事件(这里其实也算是异步),这个事件去处理收到的数据包这个人只负责收快递触发事件触发事件以后就继续收快递异常实际上也要在收到快递以后触发同一个事件(数据收到肯定要做各种处理)
解决方案八:
主要是感觉用异步多了一个打电话的过程。(系统要做资源分配等各种操作)我这个异步接收也是多级并发,异步的接收也是收到快递以后继续并发事件不去跟踪收到的快递怎么处理。
解决方案九:
我测试了收到数据后操作界面,全部接收完毕后界面会卡很久并发了近100W次的界面操作使用同步、异常的差距就在UDP缓存因为接收数据速度不一样,局域网急速发速度的时候整个缓冲区一下就被填满导致信息覆盖connect.ReceiveBufferSize=ReceiveBufferSize;默认好像是8K同步模式能基本保证客户端发送一条,服务器基本能马上接收到并发出界面操作事件。异步会因为缓冲区被覆盖导致丢失大量信息。
解决方案十:
各有利弊吧你实际上就是实现了系统给你封装好的异步的功能而已代价就是有一个线程必须在那里等待还拿快递来说,好比是派个门卫一直在那干等,还是说门卫本身也可以该干啥干啥,快递来了按门铃,门卫才去看,而已
解决方案十一:
我是初学者,不知道理解对不对。
解决方案十二:
最终就是数据到底在哪里排队的问题,是在你自己定义的线程里排队,还是在系统缓冲区里排队如果只有一个快递要来,可能同步和异步就没啥大区别而如果有非常多的快递要来,同步的方式就是来一个收一个,快递先放到门卫室排队,然后等着别人来取而异步的方式就是送快递的在大街上排排站,等着门卫来取
解决方案十三:
关键问题是如何处理粘包分包的问题用异步的方式可能比同步更难处理一些,但是绝对不是说异步本身性能上有问题导致数据丢失很有可能来了两个快递,但是门卫一次性收到了,那么你如何区分它是应该给2个人的,而不要给同一个人了也有可能某个人今天要来3个快递,但是不是一起来的,而是分别送了3次才送来的
解决方案十四:
嗯嗯就是这个意思,我理解应该是没错。因为缓冲区大小问题用异步要设置的很大(我测试的比较暴力,几台机器每秒10W个小数据包发送)用异步缓冲区必须设置的很大才能保证数据不被覆盖(同意拿100W个包比同步慢40%)同步少了IAsyncResult开销缓冲区有数据时拿走的快。
解决方案十五:
UDP本来就是不可靠协议,而且UDP的包一般不会粘包的吧(不会像TCP把各种小包打包到一起发送,就算1个字节UDP也是一个包发过来),退一步说不管怎么做这些都要处理(并发的事件)而且(UDP我打算是做信息传递,不发送大于1400的信息)我只是觉得单纯说接收数据包速度而言同步+线程的模式比直接使用异步方法效率更高。
其他方案:
也有可能某个人今天要来3个快递,但是不是一起来的,而是分别送了3次才送来的this.ReceiveData(packet,this.remoteEndPoint,null);this.remoteEndPoint可以当作是人packet可以在里面添加信息表示要三个包都到了才是完整。
其他方案:
这个主要还是看业务需求来取舍吧既然提供了同步和异步两种方式,就都是有各自的作用的不是说用异步就可以完全代替同步了有些时候该用同步还是要用同步
其他方案:
感觉为了保证收到全部的快递还是同步的好。后台能不能处理完是一回事,感觉还是比快递丢了好。异步的时候随着快递包的增加缓存区需要几何倍数增加才能保证所有快递不被挤掉。(虽然这样的情况不太可能,只是单纯的测试)
其他方案:
3.5提供的SocketAsyncEventArgs类好像也降低了IAsyncResult的开销来提高效率
其他方案:
我还测试了并发事件的时候先并发事件--->回调线程池会按照接收到的数据次序处理界面,先回调--->并发事件线程池会把接收到的数据次序打乱处理界面,
其他方案:
把包编上号,测试下看看会不会丢包再说?我也不太清楚,反正当初单独用事件触发来处理还是会少包,而用事件触发后再异步把内容交给别人处理就好多了
其他方案:
引用8楼erosna的回复:
我测试了收到数据后操作界面,全部接收完毕后界面会卡很久并发了近100W次的界面操作使用同步、异常的差距就在UDP缓存因为接收数据速度不一样,局域网急速发速度的时候整个缓冲区一下就被填满导致信息覆盖connect.ReceiveBufferSize=ReceiveBufferSize;默认好像是8K同步模式能基本保证客户端发送一条,服务器基本能马上接收到并发出界面操作事件。异步会因为缓冲区被覆盖导致丢失大量信息。
你终于拿出一些具体的东西来问了。实际上如果按照你说的“同步处理快、异步处理慢”,那么你也就看不到什么“丢失大量信息”的问题了。反之,正由于你的程序在并发处理时有bug而丢处理,并且异步系统的处理速度比你认为以为得更快许多,所以你才会搞不定的。同步、阻塞、循环,程序运行得很慢很卡,所以你才会觉得你的程序“稳定”。这时侯你应该好好看看你的程序设计问题。一般人都知道,当他异步、并发处理时,往往再写的有bug时会“丢失数据操作”,所以他就会努力找到自己的程序bug,而不会去怪“异步并发程序运行太慢所以丢数据”的。
其他方案:
嗯咯我大概总结出来了,不管同步异步,始终高强度接收数据包的情况下如果来不及处理收到的数据包(收包,后台处理)。在程序内部并发数越来越多导致并发达到极限,内存CPU需求急剧上升最终-----》程序卡死缓冲区覆盖未处理的数据包---》丢包,程序内部处理不及时也会导致最终------》程序卡死不管怎么样一个程序总有一个处理极限,达到这个极限就会出现问题。。。只能根据实际应用,网络情况来判断程序能不能承受。
其他方案:
引用22楼erosna的回复:
嗯咯我大概总结出来了,不管同步异步,始终高强度接收数据包的情况下如果来不及处理收到的数据包(收包,后台处理)。在程序内部并发数越来越多导致并发达到极限,内存CPU需求急剧上升最终-----》程序卡死缓冲区覆盖未处理的数据包---》丢包,程序内部处理不及时也会导致最终------》程序卡死不管怎么样一个程序总有一个处理极限,达到这个极限就会出现问题。。。只能根据实际应用,网络情况来判断程序能不能承受。
是的.代码使用不同的方式,可能对性能产生影响,但是终究会有极限的
其他方案:
不考虑代码质量太差的情况,只考虑正常的应用中要么是用空间换时间,也就是要速度快,占内存和CPU资源就要多要么是用时间换空间想两个都提升,代码优化的空间毕竟有限,升级硬件才是根本的解决之道台式机到极限了,就换服务器,服务器到极限了,就换服务器组