With so much emphasis on Task-Based asynchronous development, I was surprised to see that Service References in Windows Phone 8 do not support task-based implementations. Instead they use a "XYZCompleted" event-based asynchronous approach.
As a result, code like this is necessary: http://codepaste.net/fqyt47
public async Task<IEnumerable<MyService.Character>> GetCharactersAsync()
{
var _Task = new TaskCompletionSource<IEnumerable<MyService.Character>>();
var _Client = new MyService.ServiceClient();
_Client.GetCharactersCompleted += (s, e) =>
{
var _Characters = e.Result as IEnumerable<MyService.Character>;
if (e.Error != null && !_Task.TrySetException(e.Error))
System.Diagnostics.Debugger.Break();
else if (e.Cancelled && !_Task.TrySetCanceled())
System.Diagnostics.Debugger.Break();
else if (!_Task.TrySetResult(_Characters))
System.Diagnostics.Debugger.Break();
};
_Client.GetCharactersAsync();
return await _Task.Task;
}
However, this feels wrong . Is there a better, more elegant approach?
I'm surprised Windows Phone 8 doesn't have Task
-based reference creation.
That said, TaskCompletionSource
is the standard way of interoperating with various asynchronous patterns (including EAP) .
Usually it's done with extension methods which are consumable by await
but which are not async
themselves:
public Task<IEnumerable<MyService.Character>> GetCharactersTaskAsync(this ServiceClient client)
{
var tcs = new TaskCompletionSource<IEnumerable<MyService.Character>>();
client.GetCharactersCompleted += (s, e) =>
{
if (e.Error != null) tcs.SetException(e.Error);
else if (e.Cancelled) tcs.SetCanceled();
else tcs.SetResult(e.Result);
};
client.GetCharactersAsync();
return tcs.Task;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.