我使用C#(.NET Framework v4.5)爲客戶端和服務器創建新遊戲項目的服務器。在多線程套接字服務器上使用事件
我目前正在使用類似的東西來管理我的球員。
new Thread(() =>
{
connection.ListenAndSend();
}).Start();
public void ListenAndSend()
{
while(working)
{
if(someThingToRead)
{
//Listening logic here
//Here i call my event for dataReceived with the data i just read.
}
else if (queue.Count > 0)
{
Send(queue.Dequeue().Data); //Send data from the Queue
}
}
使用一個隊列是因爲我不應該訪問來自不同線程的流(它拋出InvalidOperationException異常我覺得),所以我實施的隊列從同一線程發送數據。
我認爲這大多是好的,但即時擔心的事件。
事件被解僱和工作正常,但我還沒有與多個客戶端,以便測試...
- 是在同一個線程正在執行的事件偵聽器線程?
- 我可以在多個線程同時修改字段時遇到問題嗎? (我比較有經驗的java例如,我記得一些關於Syncronize接口?)
- 它現在還沒有完成,但後來它可能會有一些事件最終會調用發送方法,所以添加數據到發送隊列(但這應該不是一個問題吧?)
這個遊戲將永遠不會爲大量的球員(可能介於2至8),如果這件事。
我有沒有看到一些嚴重的問題?
即時通訊使用隊列即時通訊認爲不管什麼線程添加數據,但將我的偵聽停止,而它正在執行事件代碼? (如果它真的在同一個線程上),雖然這不是一個真正的問題,它會同時訪問來自多個線程的字段?
更新:
我可以使所有這一切只與異步/等待?我不能看到如何使這個聽循環,但如果真的有可能請擴大答案。
另外,這answer說相反。
更新2:
現在,我過我的代碼,我知道它的工作的罰款。
正如評論指出,我可以做這個使用異步/少了很多線程等待,但:
在它會更好地使用異步/等待着,而不是線程,請記住我的遊戲服務器應該能夠根據需要獲取儘可能多的cpu /內存,如果可以的話,它的罰款也很高(當然,線程在不工作時調用睡眠)。而且我希望我的服務器儘可能地接近實時。
我也想指出,我第一次開始處理我的邏輯,遊戲地圖的序列化(約60k對象)花了大約600ms(這將是每個客戶端),所以我結束了移動序列化作業到套接字線程。
考慮到這一點,誰認爲這將是更好地使用異步/等待而不是新的線程
PD:我只是在談論我的服務器,遊戲客戶端確實使用異步/等待與溝通服務器。
你在使用'NetworkStream'嗎?因爲你不能從多個線程訪問它 - 只要你沒有兩個線程同時讀取,或者兩個線程同時寫入。 –
您執行'ListenAndSend'方法作爲後臺線程。您的事件處理程序將在同一個線程中執行(並阻止進一步接收),您可以使用https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.110)的.aspx。 –
@ C.Evenhuis是的即時通訊使用NetworkStream和我敢肯定,我從另一個線程調用寫入時得到一個異常(雖然它很可能其他線程調用讀取),但即使我可以應該我? – Nanoc