雖然試圖通過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