This recipe will describe how to translate event-based asynchronous operations to tasks. In this recipe, you will find a solid pattern that is suitable for every event-based asynchronous API in the .NET Framework class library.
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
//
// Translate Event-Based Asynchronous Operations to Tasks
//
// This recipe will describe how to translate event-based asynchronous
// operations to tasks. In this recipe, you will find a solid pattern that is
// suitable for every event-based asynchronous API in the .NET Framework class
// library.
//
// How it works...
//
// This is a very simple and elegant example of converting EAP patterns to
// tasks. The key point is to use the TaskCompletionSource<T> type, where T is
// an asynchronous operation result type.
//
// It is also important to not forget to wrap the tcs.SetResult method call into
// the try - catch block to guarantee that the error information is always set
// to the task completion source object. It is also possible to use the
// TrySetResult method instead of SetResult to make sure that the result has
// been set successfully.
//
namespace Chapter4.Recipe5
{
class Program
{
static void Main(string[] args)
{
var tcs = new TaskCompletionSource<int>();
var worker = new BackgroundWorker();
worker.DoWork += (sender, eventArgs) =>
{
eventArgs.Result = TaskMethod("Background worker", 5);
};
worker.RunWorkerCompleted += (sender, eventArgs) =>
{
if (eventArgs.Error != null)
{
tcs.SetException(eventArgs.Error);
}
else if (eventArgs.Cancelled)
{
tcs.SetCanceled();
}
else
{
tcs.SetResult((int)eventArgs.Result);
}
};
worker.RunWorkerAsync();
int result = tcs.Task.Result;
Console.WriteLine("Result is: {0}", result);
}
static int TaskMethod(string name, int seconds)
{
Console.WriteLine(
"Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name,
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 42 * seconds;
}
}
}