我使用MSDN异步样本编写Async套接字客户端和服务器类,3000 GB数据全部成功传输到单个客户端和单个数据发送线程测试。
但是当我使用for循环来创建几个线程来向服务器发送数据时,我发现在Client端,为BeginConnectCallback创建的线程总是具有相同的id。
并且所有ManualResetEvent机制都失败,所有线程在第一个线程调用ManualResetEvent.Set( )
时激活。 (每个线程都有自己的ManualResetEvent对象)
这是我的客户端日志示例:(问题是为什么线程7始终执行EndConnect作业?)
15:33:05.100数据发送线程1,BeginConnect到服务器192.168.1.100 端口6000
15:33:05.100数据发送线程2,BeginConnect到服务器 192.168.1.100端口6000
15:33:05.100数据发送线程3,BeginConnect到服务器192.168.1.100端口6000
15:33:05.102 ConnectionCallback Thread 7执行EndConnect和mreConnectDone.Set( ); 15:33:05.102 ConnectionCallback Thread 7执行EndConnect 和mreConnectDone.Set();
15:33:05.121数据发送线程1, 通过端口2650连接,插座句柄:8234
15:33:05.145 ConnectionCallback Thread 7执行EndConnect和mreConnectDone.Set( );
15:33:05.170数据发送线程2,通过端口2651连接, 套接字句柄:8235
15:33:05.177数据发送线程3,已连接 通过Port 2652,Socket Handle:8236
如果您对此感兴趣,我可以将您的源代码邮寄给您。 我的邮件是thlin.harcon@gmail.com
答案 0 :(得分:0)
.NET Framework在线程池的线程上调用为什么线程7始终执行EndConnect作业?
ConnectCallback
方法。如果线程7在给定时刻没有被任何工作占用,那么线程池管理器可能决定在该线程上运行回调。当所有回调都在该单个线程上执行时,这是线程池的正常行为。
如果要通知调用BeginConnect
的线程,则需要将某些内容传递给BeginConnect
作为最后一个参数Object state
。例如,您可以传递相应的ManualResetEvent
对象,然后通过回调方法发出信号。
BTW,您提到的MSDN示例显示了如何在回调方法中检索ManualResetEvent
对象(或传递给BeginConnect
的任何其他对象)的示例:
// Retrieve the socket from the state object.
Socket client = (Socket) ar.AsyncState;