c# – 为什么SocketAsyncEventArgs的Completed回调在新创建的线
发布时间:2020-12-15 06:47:21 所属栏目:百科 来源:网络整理
导读:我有一个简单的客户端应用程序,从网络接收字节缓冲区,吞吐量低.这是代码: private static readonly HashSetint _capturedThreadIds = new HashSetint();private static void RunClient(Socket socket){ var e = new SocketAsyncEventArgs(); e.SetBuffer(ne
我有一个简单的客户端应用程序,从网络接收字节缓冲区,吞吐量低.这是代码:
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). 似乎线程测试总是使用新创建的线程完成,而不是将线程移入和移出池.我想这样做对于大多数应用程序来说更好,因为它避免了使用未使用的线程. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |