我在一个令我困惑的应用程序中有一些奇怪的行为。
我创建了一个线程,我们称之为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 的线程和正在执行回调的线程的 ManagedThreadId,我发现有时它们具有相同的 ThreadId!
那可能吗?怎么会这样?关于我做错了什么的任何建议?
评论:实际代码并不完全一样,Transport 是 UDPClient 的包装器,它允许轻松更改传输层,锁不是真正的锁而是自旋锁......但概念本身或多或少是我写下来的.