I ran into an issue today that took me a while to figure out what was happening so I thought I'd share.
I wanted to take advantage of the asynchronous function: NamedPipeServerStream WaitForConnectionAsync to create a multi client Named Pipe server. I also wanted to prevent other instances of the server running so I used a Mutex like this:
//Named pipe server run method 
public async Task Run()
{
     using (var mutex = new Mutex(true, mutexName, out var createdNew))
            {
                if (createdNew)
                { 
                    try
                    {
                        await RunInternal();
                    }
                    finally
                    {
                        mutex.ReleaseMutex();
                    }
                }
            }
}
Everything looked and ran normally until the RunInternal method completed. The call to ReleaseMutex was throwing a synchronization exception:
ApplicationException: Object synchronization method was called from an unsynchronized block of code.
I didn't realize (or appreciate) that the await keyword returns control on a different 
thread.  Although method looks continuous, the Mutex was right to 
complain that a thread that didn't create the Mutex was trying to release it.
public void Run()
{
       using (var mutex = new Mutex(true, mutexName, out var createdNew))
       {
         if (createdNew)
         { 
           try
           {
             //Synchronously wait so that the finally block executes in current thread.
             //This is a requirement of the Mutex.ReleaseMutex method.
             RunInternal().Wait();
           }
           finally
           {
             mutex.ReleaseMutex();
           }
         }
       }
     }
}
Maybe there's better solution but this worked for me, much more to learn I'm sure.
 
No comments:
Post a Comment