我有一個多線程的網絡應用程序使用UdpClient
,TcpClient
,TcpListener
,並處理接收的連接和接收數據使用例如。 BeginReceive()
EndReceive()
回調模式。我是否需要異步同步TCP/UDP客戶端BeginReceive回調
使用UdpClient爲例,在該模式中工作的一般流程我現在用的就是:
- 呼叫
UdpClient.BeginReceive()
- 接收到一個數據包時,將執行接收回調。
- 致電
UdpClient.EndReceive()
收集數據報。 - 再次致電
UdpClient.BeginReceive()
準備接收另一個數據報。 (3)處理收到的數據報( - )。
- 重複2 - 5爲多個的數據報被接收
問:既然僅存在單個UdpClient
對象,並且由於下一個BeginReceive()
之前總是調用EndReceive()
圖案,是否需要鎖定/爲這些調用同步訪問對象UdpClient
?
在我看來,另一個線程不可能干擾這個工作流程或使這些調用不是原子的。 TcpClient.BeginReceive()
和TcpListener.BeginAcceptTcpClient()
的模式非常相似。
獎金問:單UdpClient
對象需要申報static
(和static
鎖object
如果需要)?
注意:我是而不是詢問是否需要執行任何鎖定操作。數據報處理。僅針對這種模式和對象。
EDIT
作爲說明,(忽略異常處理)是此代碼:
private void InitUDP()
{
udpclient = new UdpClient(new IPEndPoint(IPAddress.Any, Settings.Port));
udpclient.BeginReceive(new AsyncCallback(receiveCallback), udpclient);
}
private void receiveCallback(IAsyncResult ar)
{
UdpClient client = (UdpClient)ar.AsyncState;
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);
byte[] datagram = client.EndReceive(ar, ref ep);
udpclient.BeginReceive(new AsyncCallback(receiveCallback), udpclient);
processDatagram();
}
比這個代碼實際上不同或更少的保護:
private void InitUDP()
{
udpclient = new UdpClient(new IPEndPoint(IPAddress.Any, Settings.Port));
udpclient.BeginReceive(new AsyncCallback(receiveCallback), udpclient);
}
private void receiveCallback(IAsyncResult ar)
{
UdpClient client = (UdpClient)ar.AsyncState;
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);
lock(_lock)
{
byte[] datagram = client.EndReceive(ar, ref ep);
udpclient.BeginReceive(new AsyncCallback(receiveCallback), udpclient);
}
processDatagram();
}
'UdpClient'成員函數不是線程安全的,所以如果多個線程訪問同一個實例,那麼你有問題。我不確定這是否是你的問題。 – MicroVirus
雖然這是個問題 - 如果在下一個'BeginReceive()'之前始終調用EndReceive()',是否有可能通過這些回調訪問同一個實例?我需要鎖定這些電話嗎? – khargoosh
你是控制線程的人,所以你決定什麼線程訪問什麼。那有可能嗎?是的,如果回調可以合法地訪問實例,例如當它是公開的或者回調是同一實例的成員時 - 以某種方式,如果您可以編寫代碼來訪問回調中的實例並編譯它,是的,你可以訪問它。但是,除非我誤解,否則這不是您真正想要回答的問題,因爲像我說的那樣,您決定每個回調/線程的功能,對嗎? – MicroVirus