Edit (after acceptance)
It might not be immediately apparent but @Servy's answer is correct without needing a custom implementation of Unwrap
under monodroid - in my comments I said it didn't exist, but it definitely does.
End edit
I'm writing a bunch of apps that use our RESTful web services and, despite thinking I know how to use tasks properly it turns out I don't. The scenario is that I have code implemented for Windows Store - using async/await
and I need to implement something near-identical for MonoDroid - which doesn't have that (without some build hacks that I don't want to use).
I've boiled down the problem for this question to a simple set of tasks for getting an integer asynchronously, then, in the continuation, firing another asynchronous task that turns a string built from that integer. In C#5 this would be:
Note - of course I'm using Task.FromResult<T>
here in place of actual async code
private async Task<string> GetStringAsync()
{
return await GetStringFromIntAsync(await GetIntAsync());
}
private async Task<int> GetIntAsync()
{
return await Task.FromResult(10);
}
private async Task<string> GetStringFromIntAsync(int value)
{
return await Task.FromResult(value.ToString());
}
To convert this to a continuation-based pattern I tried this:
private Task<string> GetStringAsync()
{
//error on this line
return GetIntAsync().ContinueWith(t => GetStringFromIntAsync(t.Result));
}
private Task<int> GetIntAsync()
{
return Task.FromResult(10);
}
private Task<string> GetStringFromIntAsync(int value)
{
return Task.FromResult(value.ToString());
}
However, this isn't correct because the GetStringFromIntAsync
method returns a Task<string>
meaning that the continuation ends up returning a Task<Task<string>>
instead of a Task<string>
.
I've found that explicitly waiting on the GetStringFromIntAsync
method does work, however:
private Task<string> GetStringAsync()
{
return GetIntAsync().ContinueWith(t =>
{
var nested = GetStringFromIntAsync(t.Result);
nested.Wait();
return nested.Result;
});
}
The question is, though - is that the right way to do it - can I not return a continuation of some sort that the caller then waits on?
I have used tasks quite a bit - but not to chain tasks of different types together like this (except with async
/await
of course) - and feel a bit like I'm going mad here - so any help is greatly appreciated.