Jeremy
Jeremy

Reputation: 46340

How to block until an asynchronous call is complete?

I have a method which calls an asynchronous method, and a callback which is fired when the asynchronous method finishes.

I want my method to appear syncrhonous, so I've created an AutoResetEvent, called the asyncrhonous method, the call WaitOne() on the AutoResetEvent instance, and I call Set() in the callback method. Something like this (simplified for this example):

private System.Threading.AutoResetEvent waitRun_m;
public void RunSynchronous()
{
    waitRun_m = new System.Threading.AutoResetEvent(false);
    CallAsynchronousMethod();

    waitRun_m.WaitOne();
}

private void Callback()
{
    waitRun_m.Set();
}

Now, is it possible for the call to CallAsynchronousMethod to complete before WaitOne() to be called - causing Set() to be called before WaitOne(). Is there a better way to do this, to avoid this potential issue?

Upvotes: 1

Views: 6722

Answers (3)

kossib
kossib

Reputation: 490

As Daniel and nobugz said using AutoResetEvent might be dangerous. You might be calling waitRun_m.Set(); before you call waitRun_m.WaitOne(); when an async operation is very short. I'd prefer something like this. That way you are sure that you will first enter the wait state, and then call the Pulse method. Plus you don't have to Close the AutoResetEvent which is often forgoten.

private readonly object m_lock = new object();
public void RunSynchronous()
{
    lock(m_lock) {
        CallAsynchronousMethod();
        Monitor.Wait(m_lock);
    }
}

private void Callback()
{
    lock(m_lock)
        Monitor.Pulse(m_lock);
}

Upvotes: 1

Daniel Yankowsky
Daniel Yankowsky

Reputation: 7006

I believe this will answer your question:

Calling Set signals AutoResetEvent to release a waiting thread. AutoResetEvent remains signaled until a single waiting thread is released, and then automatically returns to the non-signaled state. If no threads are waiting, the state remains signaled indefinitely.

You have to be careful, though, because now RunSynchronous doesn't look thread safe. If two different threads call it in an overlapping manner, all hell could break loose.

Upvotes: 7

Hans Passant
Hans Passant

Reputation: 941317

It is not an issue, the event getting Set before you WaitOne is fully supported. AutoResetEvent would be quite unusable if this wasn't the case.

Upvotes: 3

Related Questions