2013-12-12 14 views
-1

我使用MSDN异步样例编写一个Async套接字客户端和服务器类,3000 GB数据全部成功转移到单个客户端和单个数据发送线程测试下。 但是,当我使用for循环创建多个线程发送数据到服务器时,我发现在客户端,为BeginConnectCallback创建的线程始终具有相同的ID。 和所有ManualResetEvent机制都失败,所有线程在第一个线程调用ManualResetEvent.Set()时激活。 (每个线程都有它自己的ManualResetEvent对象)c#套接字总是用同一线程EndConnection

这里是我的客户端日志样本:(问题是,为什么它总是线程7做EndConnect工作?)

15:33:05.100的数据发送线程, 1,BeginConnect到服务器192.168.1.100 端口6000
15:33:05.100数据发送线程2,开始连接到服务器 192.168.1.100端口6000
15:33:05.100数据发送线程3,开始连接到服务器192.168.1.100端口6000
15:33:05.102 ConnectionCallback线程7执行EndConnect和mreConnectDone.Set( );
15:33:05.102 ConnectionCallback线程7执行EndConnect 和mreConnectDone.Set();
15:33:05.121数据发送线程1, 通过端口2650连接,套接字句柄:8234
15:33:05.145 ConnectionCallback线程7执行EndConnect和mreConnectDone.Set( );
15:33:05.170数据发送线程2,经由端口2651, 插座手柄连接:8235
15:33:05.177的数据通过端口2652发送线程3,连接 ,插座手柄:8236

我如果您对此感兴趣,可以向您发送源代码。 我的邮箱是[email protected]

MSDN sample URL

+0

不要邮件的源代码 - 交您所指的*相关*部分。 – JeffRSon

回答

0

为何总线程7做EndConnect工作?

ConnectCallback方法由.NET Framework在线程池的线程上调用。如果在给定的时刻线程7没有被占用,那么线程池管理器可能会决定在该线程上运行回调。当所有的回调都在该单线程上执行时,这是线程池的正常行为。

如果你想通知调用BeginConnect的线程,那么你需要将一些东西传递给BeginConnect作为最后一个参数Object state。例如,您可以传递相应的ManualResetEvent对象,然后从回调方法发出信号。

顺便说一句,你提到的MSDN示例展示了一个例子,你如何检索回调方法的ManualResetEvent对象(或你传递给BeginConnect任何其他对象):

// Retrieve the socket from the state object. 
    Socket client = (Socket) ar.AsyncState;