2017-01-30 1 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를 사용해보십시오. 이처럼 : 그것은으로 ManualResetEvent (false)를보다 더 빠른 원인이 하나의 프로세스에 의해 제한 있기 때문에 차례로

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 클래스를 사용하는 것이 좋습니다. 물론 다른 프로그램에서 잠금을 사용할 필요가없는 경우.

+0

'AutoResetEvent'는 슬림 버전으로'Monitor' 사용법과 거의 비슷합니다. – VMAtm