Working on a new WinPhone app the other day I encountered an interesting problem which made me scratch my head quite a bit. I needed to read the list of appointments from the phone’s calendar. No big deal, right? Using the MVVM pattern I created a separate view model for my page and a service where I wanted to put all my phone specific stuff. The initial signature of my method was
public IEnumerable<Appointment> GetAppointments();
When trying to implement the method I found out that the calendar API uses the old style event based async pattern (EAP). I tried couple of different methods to wrap the async call and the result from the event in a single method call and failed miserably. After that I tried changing the method to the new async/await style. I knew I had to return a Task<T> so the signature of my method became
public Task<IEnumerable<Appointment>> GetAppointments();
But I still did not know how to make it work. And then I finally came across the TaskCompletionSource class that already solves my problem:
public Task<IEnumerable<Appointment>> GetAppointments()
{
return Task.Run(() =>
{
var tcs = new TaskCompletionSource<IEnumerable<Appointment>>();
var appts = new Appointments();
appts.SearchCompleted += (o, e) =>
{
tcs.TrySetResult(e.Results);
};
appts.SearchAsync(DateTime.Today, DateTime.Today.AddDays(1), "appointments");
return tcs.Task;
});
}
Beautiful, isn’t it?
