Вот сам экстеншн. Пример для наглядности ниже
public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next)
{
if (first == null)
{
throw new ArgumentNullException("first");
}
if (next == null)
{
throw new ArgumentNullException("next");
}
var tcs = new TaskCompletionSource<T2>();
first.ContinueWith(delegate
{
if (first.IsFaulted)
{
tcs.TrySetException(first.Exception.InnerExceptions);
}
else if (first.IsCanceled)
{
tcs.TrySetCanceled();
}
else
{
try
{
var t = next(first.Result);
if (t == null)
{
tcs.TrySetCanceled();
}
else
{
t.ContinueWith(delegate
{
if (t.IsFaulted)
{
tcs.TrySetException(t.Exception.InnerExceptions);
}
else if (t.IsCanceled)
{
tcs.TrySetCanceled();
}
else
{
tcs.TrySetResult(t.Result);
}
}, TaskContinuationOptions.ExecuteSynchronously);
}
}
catch (Exception exc)
{
tcs.TrySetException(exc);
}
}
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
Ну и пример обещанный. Здесь в отличии от всем известного HttpClient.GetStringAsync(url) добавляется URL в два экшепшена. Кто не вкурсе такие же эксепшены как впримере кидает framework, но
без урлы.
public static Task<string> GetAsStringAsync(this HttpClient client, string url)
{
Task<HttpResponseMessage> taskGet;
try
{
taskGet = client.GetAsync(url);
}
catch (Exception ex)
{
throw new ArgumentException(string.Format("URL '{0}' is not suitable with HttpClient", url), "url", ex);
}
Task<string> taskRead = taskGet.Then(response =>
{
if (response.StatusCode != HttpStatusCode.OK)
throw new HttpRequestException(string.Format(
"Status of '{0}' response isn't OK(200). Status is {1}. Phrase is '{2}'",
url,
response.StatusCode,
response.ReasonPhrase));
return response.Content.ReadAsStringAsync();
});
return taskRead;
}
Второй экстеншн ругать не обязательно. Так привел, для примера использования.
P.S. Task.Then случайно нашел. Я его так и не нагуглил. Странно что его нет в dotnet. Или я плохо искал?
Здравствуйте, VladCore, Вы писали:
VC>P.S. Task.Then случайно нашел. Я его так и не нагуглил. Странно что его нет в dotnet. Или я плохо искал?
Если гуглить по "task, C#, functor", то гуглится
https://weblogs.asp.net/dixin/category-theory-via-c-sharp-6-functor-like-tuple-task-and-iqueryable
Когда таски уже были, а async/await еще нет, действительно было странно. Сейчас уже не так странно. Комбинировать таски в динамике приходится гораздо реже.