Thursday, April 14, 2011

Asynchronous Calls Newbie Question

Good Day,

I am working on a small project where I need to make two asynchronous calls right after another.

My code looks something like this:

AsynchronousCall1(); AsynchronousCall2();

The problem I'm having is that both calls take anywhere from one to two seconds to execute and I never know which one will finish last. What I'm looking for is a way to determine who finishes last. If Call1() finishes last, I do one thing. If Call2() finishes last, I do another thing.

TIA,

coson

From stackoverflow
  • I believe there is a method that is a member of the Thread class to check on a specific thread and determine its status. The other option would be to use a BackgroundWorker instead, as that would allow you to spell out what happens when that thread is finished, by creating seperate methods.

    The "thread-unsafe" option would be to use a class variable, and at the end of each thread if it isn't locked / already have the other thread's value, don't set it. Otherwise set it.

    Then when in your main method, after the call to wait for all threads to finish, test the class variable.

    That will give you your answer as to which thread finished first.

  • This is a simple example of using a lock to ensure that only one thread can enter a piece of code. But it's a general example, which may or may not be best for your application. Add some details to your question to help us find what you're looking for.

       void AsynchronousCall1()
       {
            // do some work
            Done("1");
       }
    
       void AsynchronousCall2()
       {
            // do some work
            Done("2");
       }
    
       object _exclusiveAccess = new object();
       volatile bool _alreadyDone = false;
       void Done(string who)
       {
            lock (_exclusiveAccess)
            {
                 if (_alreadyDone)
                     return;
    
                 _alreadyDone = true;
                 Console.WriteLine(who + " was here first");
            }
       }
    
    eglasius : +1 y, that will work
  • You may want to check out the Blackboard design pattern: http://chat.carleton.ca/~narthorn/project/patterns/BlackboardPattern-display.html. That pattern sets up a common data store and then lets agents (who know nothing about one another -- in this case, your async calls) report their results in that common location. Your blackboard's 'supervisor' would then be aware of which call finished first and could direct your program accordingly.

  • You can do this with two ManualResetEvent objects. The idea is to have the main thread initialize both to unsignaled and then call the asynchronous methods. The main thread then does a WaitAny on both objects. When AsynchronousCall1 completes, it signals one of the objects. When AsynchronousCall2 completes, it signals the other. Here's code:

    ManualResetEvent Event1 = new ManualResetEvent(false);
    ManualResetEvent Event2 = new ManualResetEvent(false);
    
    void SomeMethod()
    {
        WaitHandle[] handles = {Event1, Event2};
        AsynchronousCall1();
        AsynchronousCall2();
        int index = WaitHandle.WaitAny(handles);
        // if index == 0, then Event1 was signaled.
        // if index == 1, then Event2 was signaled.
    }
    
    void AsyncProc1()
    {
        // does its thing and then
        Event1.Signal();
    }
    
    void AsyncProc2()
    {
        // does its thing and then
        Event2.Signal();
    }
    

    There are a couple of caveats here. If both asynchronous methods finish before the call to WaitAny, it will be impossible to say which completed first. Also, if both methods complete very close to one another (i.e. call 1 completes, then call 2 completes before the main thread's wait is released), it's impossible to say which one finished first.

    Greg D : This doesn't really change the race condition that already exists. Don't your caveats defeat the point of the entire answer?

0 comments:

Post a Comment