private static Readonly HashSet<int> _capturedThreadIDs = new HashSet<int>();private static voID runclIEnt(Socket socket){ var e = new socketasynceventargs(); e.SetBuffer(new byte[10000],10000); e.Completed += SocketAsyncEventsArgsCompleted; Receive(socket,e);}private static voID Receive(Socket socket,socketasynceventargs e){ var isAsynchronous = socket.ReceiveAsync(e); if (!isAsynchronous) SocketAsyncEventsArgsCompleted(socket,e);}private static voID SocketAsyncEventsArgsCompleted(object sender,socketasynceventargs e){ if (e.Lastoperation != SocketAsyncoperation.Receive || e.socketError != SocketError.Success || e.BytesTransferred <= 0) { Console.Writeline("Operation: {0},Error: {1},BytesTransferred: {2}",e.Lastoperation,e.socketError,e.BytesTransferred); return; } var thread = Thread.CurrentThread; if (_capturedThreadIDs.Add(thread.ManagedThreadID)) Console.Writeline("New thread,ManagedID: " + thread.ManagedThreadID + ",NativeID: " + GetCurrentThreadID()); //Console.Writeline(e.BytesTransferred); Receive((Socket)sender,e);}
应用程序的线程行为非常好奇:
> SocketAsyncEventsArgsCompleted方法经常在新线程中运行.我会预料到,在一段时间后,不会创建新的线程.我会期望线程被重用,因为线程池(或IOCP线程池),因为吞吐量非常稳定.
>线程数保持不变,但是在进程资源管理器中可以看到线程经常被创建和销毁.同样,我也不希望创建或销毁线程.
你可以解释应用行为吗?
编辑:“低”吞吐量是每秒20个消息(大约200 KB / s).如果我将吞吐量提高到每秒超过1000条消息(50 MB / s),则应用程序行为不会改变.
解决方法 低应用程序吞吐量本身不能解释线程的创建和破坏.套接字每秒接收20条消息,这足以保持线程活动(等待线程在花费10秒空闲后被破坏).这个问题与线程池线程注入有关,即线程创建和销毁策略.线程池线程经常被注入和销毁,以便测量新线程对线程池吞吐量的影响.
这被称为线程探测.在频道9视频CLR 4 – Inside the Thread Pool中有明确的解释(跳到26:30).
似乎线程测试总是使用新创建的线程完成,而不是将线程移入和移出池.我想这样做对于大多数应用程序来说更好,因为它避免了使用未使用的线程.
总结以上是内存溢出为你收集整理的c# – 为什么SocketAsyncEventArgs的Completed回调在新创建的线程中经常执行,而不是使用有界线程池?全部内容,希望文章能够帮你解决c# – 为什么SocketAsyncEventArgs的Completed回调在新创建的线程中经常执行,而不是使用有界线程池?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)