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?