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)
Thread t = new Thread(
// Return value directly to local variable.
returnedData = BigComponent.DoHeavyProcessing();
bool success = t.Join(timeout); // Wait for the thread until the timeout expires.
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.