Search code examples
winformsc#-3.0asynchronousmultithreadingblocking

Best Practice: Blocking execution while waiting for an Async method


I am trying to adapt an existing program (internally written) to use a different library than it originally did. I've abstracted most of library-specific code away (seems to be the easier part).

The issue is, the old library would execute a call using a blocking method, and our internal program is expecting a blocking method to be called, but the new library uses an async method.

I was wondering what the best practice would be for waiting for the async operation to complete. My first thought was to have a boolean flag called completed, and spin in a while loop until completed == true.

I should note that this is for a quick proof of concept I'm trying to put together for my stakeholder, and if the stakeholders sign off on the project, I'm going to rewrite the offending part of our program. But for the time being, I need to just wait for the block the function calling the async method until the async call is complete


Solution

  • Instead of a flag, I'd think you'd want to use something like a mutex.

    In order to do this, that library needs to have an event to notify you once your async call is done. It would look like this:

    1. Create your mutex
    2. In your async complete method, add in 'myMutex.Release();"
    3. In your main method, after you call the async method, add in "myMutex.WaitOne();". This will block the thread until your async call is complete.

    It's been a while since I've used this stuff, but I'm pretty sure that's how it should work.

    edit: Oops, I think I was thinking of a semaphore, not mutex:

        private static Semaphore mySemaphore = new Semaphore(0, 1);
    
        static void Main(string[] args)
        {
            Console.WriteLine("Waiting on async call");
            (new Thread(ASyncCallCompleted)).Start();
            mySemaphore.WaitOne();
            Console.WriteLine("Waiting Completed");
        }
    
        private static void ASyncCallCompleted()
        {
            Thread.Sleep(5000);
            mySemaphore.Release();
        }
    

    edit #2: Per Thorarin's suggestion; it sounds like this class was designed to handle situations like this in .Net:

        private static AutoResetEvent mySync = new AutoResetEvent(false);
    
        static void Main(string[] args)
        {
            Console.WriteLine("Waiting on async call");
            (new Thread(ASyncCallCompleted)).Start();
            mySync.WaitOne();
            Console.WriteLine("Waiting Completed");
            Console.Read();
        }
    
        private static void ASyncCallCompleted()
        {
            Thread.Sleep(5000);
            mySync.Set();
        }