2017-01-30 85 views
0

我試圖使用的ManualResetEvent做出旗語樣的情況,我已經把WaitOne,在他們的正確的地方SetReset。該WaitOne指令被稱爲一個監聽線程,而地方TCP閱讀之後:如何等待ManualResetEvent.WaitOne(),以在移動之前達成?

var networkStream = _clientSocket.GetStream(); 
networkStream.Read(bytesFrom, 0, Convert.ToInt32(_clientSocket.ReceiveBufferSize)); 
_mainthreadControl.WaitOne(Timeout.Infinite); 

而且SetReset指令稱爲在另一個線程,所以插座將不會在競爭:

try 
{ 
    //some code 
    _mainthreadControl.Reset(); 
    //some code that uses the same socket as above 
    _mainthreadControl.Set(); 
} 
catch (Exception ex) 
{ 
    //ignored 
} 

但是我需要代碼在達到Reset時停止,並且只有在達到(並執行)WaitOne之後纔會停止,因此僅在競爭線程等待之後運行Reset以下的代碼。

我不知道如果我是很清楚,所以我很高興來添加所需的詳細信息。提前致謝。

+0

什麼是解決這個問題的約束?顯而易見的是使用一個信號量,並且只是移動代碼,以便任一代碼塊在使用套接字之前獲取信號量並在之後發佈。但我覺得你不想那麼做。那麼我們可以改變什麼?我們不能改變什麼? –

+0

你有正確的感覺。問題是,我試圖修補了一些糟糕的代碼,我沒有太多的時間來完全修復代碼,作爲一個事實的問題,我決定完全重寫,但在此期間一些修復需要完成,所以這就是爲什麼我要改變代碼的「紀律」而過於謹慎。但是我認爲@AlexNetrebesky給出的答案不會太過激烈。 –

回答

2

如果套件爲您服務。請嘗試使用其他AutoResetEvent。就像這樣:

var _additionalControl = new AutoResetEvent(false); 

// code gap 

var networkStream = _clientSocket.GetStream(); 
networkStream.Read(bytesFrom, 0, Convert.ToInt32(_clientSocket.ReceiveBufferSize)); 
_additionalControl.Set(); 
_mainthreadControl.WaitOne(Timeout.Infinite); 

// code gap 

try 
{ 
    //some code 
    _mainthreadControl.Reset(); 
    _additionalControl.WaitOne(Timeout.Infinite); 
    //some code that uses the same socket as above 

    _mainthreadControl.Set(); 
} 
catch (Exception ex) 
{ 
    //ignored 
} 

反過來我建議使用System.Threading.Monitor類,因爲它比的ManualResetEvent(假)來得更快,因爲它是由單個進程的限制。如果當然,如果你不需要在另一個程序中使用鎖定。

+0

'AutoResetEvent'具有超薄版本,幾乎與'Monitor'使用情況一樣快。 – VMAtm

相關問題