0

I'm trying to use ManualResetEvent to make a semaphore-like situation and I have placed WaitOne, Set and Reset in their right places. The WaitOne instruction is called in a listener thread and is places right after a tcp reading:

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

And Set and Reset instructions are called in another thread, so the socket won't get competed over:

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

But I need the code to stop when it reaches Reset, and only continue after the WaitOne is reached (and executed), so the code below Reset only runs after the competing thread is waiting.

I don't know if I was clear enough, so I'm glad to add details as needed. Thanks in advance.

  • What are the constraints on solving this problem? The obvious thing is to use a semaphore and just move code around so that either block of code acquires the semaphore before using the socket and releases afterwards. But I get the feeling you don't want to do that. So what can we change and what can we not change? – Damien_The_Unbeliever Jan 30 '17 at 11:33
  • You got the right feeling. The thing is that I'm trying to patch up some badly written code, and I haven't had much time to fully fix the code, as a matter of a fact, I decided to fully rewrite it, but in the mean time some fixing needs to be done, so that's why I'm being overcautious with changing the "discipline" of the code. But I think the answer given by @AlexNetrebesky will work without being too drastic of a change. – Guilherme Lofrano Corneto Jan 30 '17 at 13:23

1 Answers1

2

If it suites for you. Please try to use additional AutoResetEvent. Like this:

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
}

In turn I recommend to use System.Threading.Monitor class, cause it's more faster than ManualResetEvent(false), because it's restricted by the single process. If course if you don't need to use lock in another program.

Alex Netrebsky
  • 251
  • 1
  • 7