Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations
Waiting for a return value from an asynchronous method

The topic of the post might not make sense, initially. If I invoke a method asynchronously, why would I want to wait for a return value? And if I'm waiting, what's the point of launching it asynchronously?

Well, the most common scenario is when I want to run a process that could take time and might freeze on me, but I want to limit the time it can take and throw an exception if the timeout is exceeded. This means running the main logic in a worker thread, which means we have to find a way to get the result back to the calling method.

A simple pattern for this can take advantage of C#'s anonymous delegates to pass the return value directly into a local variable in the calling method. This means we don't have to rely on a class member to pass the info, which would need more work in a multithreaded scenario. The end result is very simple:

public MyObject GetData(TimeSpan timeout)
{
   MyObject returnedData;
   Thread t = new Thread(
                         delegate() 
                         {
                            // Return value directly to local variable.
                            returnedData = BigComponent.DoHeavyProcessing();
                         });
   t.Start();
   bool success = t.Join(timeout); // Wait for the thread until the timeout expires.
   if (success)
      return returnedData;
   else
      throw new TimeoutException();
}

Behind the scenes, the compiler will build a new anonymous type for my delegate method, and will add code to synchronize the new object I create inside the anonymous delegate into the local variable in GetData(). Simple and elegant.

Published Tuesday, July 24, 2007 11:56 AM by Avner Kashtan

Comments

# re: Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 5:11 AM

Did you try using the ManualResetEvent. I think that this is its whole purpose...

Guy Burstein

# re: Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 5:16 AM

ManualResetEvent won't help me synchronize the data between the threadfunc and the main method. It would just be a replacement for the Thread.Join method, so instead of Join I can flip the ResetEvent in the threadfunc, and wait on it outside. Not much of a difference. It has the same timeout behavior.

Avner Kashtan

# re: Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 6:27 AM

I see the elegance of the code, but I'm not sure I understand the usage. Your main thread is waiting on the worker to finish and it blocks all other processing from happening. Or am I missing something?

Fernando Felman

# re: Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 6:58 AM

Exactly. I don't want to run this asynchronously. I want it synchronous - by cancellable. If BigComponent doesn't give me any mechanisms to abort DoHeavyProcessing() after a given timeout, this technique does.

Avner Kashtan

# re: Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 7:06 AM

Last comment should read "synchronous - BUT cancellable".

Avner Kashtan

# University Update-C#-Waiting for a return value from an asynchronous method@ Tuesday, July 24, 2007 3:57 PM

Pingback from  University Update-C#-Waiting for a return value from an asynchronous method

University Update-C#-Waiting for a return value from an asynchronous method

# Allowing timeout on long-running operations - possible bug@ Monday, August 27, 2007 3:18 AM

A while ago, I wrote about a simple pattern to allow us to put a timeout limitation on a long running

Miscellaneous Debris

# Allowing timeout on long-running operations - possible bug@ Monday, August 27, 2007 3:18 AM

A while ago, I wrote about a simple pattern to allow us to put a timeout limitation on a long running

Miscellaneous Debris

# Execute code within timeout using threads and lambda@ Thursday, August 21, 2008 2:29 AM

Via this post . Following is a quick way to execute code and limiting it within a certain timeout. Note

Zuker On Foundations

Leave a Comment

(required) 
(required) 
(optional)
(required)