2009-02-26 93 views
0

我在令人困惑的应用程序中遇到一些奇怪的行为。线程池可以重用一个标准线程吗?

我创建了一个线程,我们称它为worker,它负责处理通信请求。当线程使用请求并发送消息时,客户端在管道上写入数据。现在

,该线程的主循环有这样的事情:

lock(this) 
{ 
    object_id = Transport.BeginSend(xxx, xxx, callback, yyy) 
    clientsObjects[object_id] = client_id; 
} 

现在回调需要访问CLIENT_ID(它有点超过我写的复杂,但事情是回调接收OBJECT_ID,只是假设BeginSend是UdpClient.BeginSend通话

void Callback(IAsyncResult ar) 
{ 
    State st = (State)ar; 
    lock(this) 
    { 
    client_id = clientsObjects[st.object_id] 
    } 
} 

锁是因为有回调可能会触发如此之快,它实际上发生之前clientsObjects[object_id] = client_id;可以执行...

好的,现在..问题是它不能正常工作,它现在工作,然后......为什么?如果我跟踪正在执行BeginSend的线程的ManagedThreadIds和正在执行回调的线程,我发现有时它们具有相同的ThreadId!

这可能吗?这怎么可能发生?任何关于我在做什么错误的建议?

评论:实际的代码并不完全像这样,Transport是UDPClient的一个包装,它允许轻松改变传输层,锁不是真正的锁,但是自旋锁......但是这个概念本身或多或少是我的已经写下来了。

回答

1

Here是一篇较早的文章,讲述了Stream.BeginRead()函数实际上是同步操作的,而不是像您期望的那样异步操作。这篇文章是从2004年开始的,所以我假定它指的是.NET 1.0/1.1。这篇文章并没有特别提到UdpClient.BeginSend(),但我经常想知道Socket的东西里的BeginXXX函数有时会有相同的行为,特别是如果有数据需要立即读取的话。查看网页可能是值得的,看看这是否有可能。

是否可以通过BeginSend()函数的状态参数将client_id传递给回调函数?

object_id = Transport.BeginSend(xxx, xxx, Callback, client_id); 
+0

令人惊讶的是,确实有时异步调用变为同步...什么是混乱! – 2009-02-26 15:10:03