虽然试图通过BeginSend调用为队列发送消息,但看起来像是阻塞调用。C#Socket.BeginSend有时似乎同步行为?
Specificly我:
public void Send(MyMessage message)
{
lock(SEND_LOCK){
var state = ...
try {
log.Info("Begin Sending...");
socket.BeginSend(message.AsBytes(),0, message.ByteLength, SocketFlags.None,
(r) => EndSend(r), state);
log.Info("Begin Send Complete.");
}
catch (SocketException e) {
...
}
}
}
的回调将是这样的:
private void EndSend(IAsyncResult result) {
log.Info("EndSend: Ending send.");
var state = (MySendState) result.AsyncState;
...
state.Socket.EndSend(result, out code);
log.Info("EndSend: Send ended.");
WaitUntilNewMessageInQueue();
SendNextMessage();
}
大部分能正常工作的时间,但有时它挂起。记录表明当BeginSend和EndSend在相同的线程上执行时会发生这种情况。 WaitUntilNewMessageInQueue阻塞,直到队列中有新消息,所以当没有新消息时,它可以等待退出一段时间。
至于我可以告诉这个真的不应该是一个问题,但在某些情况下BeginSend导致死锁情况EndSend被阻塞WaitUntilNewMessageInQueue(预期)块,但发送被阻塞BeginSend作为回报,因为它似乎正在等待EndSend callback te return(not expected)。
这种行为并不是我期待的。为什么BeginSend有时会阻止回调没有及时返回?
你试过我的建议? – jgauffin 2010-10-28 12:30:51
是的,虽然我还没有完成。允许异常消除需要重构整个设计。删除锁定会导致部分单元测试失败,但我怀疑这些是可恢复的未处理的异常,但需要进一步调查。 – DefLog 2010-10-29 10:14:45
那么我的问题解决了,但我仍然不清楚为什么我首先发生。我认为自己非常熟悉线程,但显然我对套接字的理解是缺乏的,所以我决定花一些时间来研究这个主题。任何refernces将不胜感激。 – DefLog 2010-11-01 10:20:19