поругайте Task.Then extention от MS
От: VladCore  
Дата: 23.07.16 21:06
Оценка:
Вот сам экстеншн. Пример для наглядности ниже
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. Или я плохо искал?
Отредактировано 23.07.2016 21:07 VladCore . Предыдущая версия .
Re: поругайте Task.Then extention от MS
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.07.16 05:55
Оценка:
Здравствуйте, 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 еще нет, действительно было странно. Сейчас уже не так странно. Комбинировать таски в динамике приходится гораздо реже.
Re: поругайте Task.Then extention от MS
От: Sinix  
Дата: 24.07.16 07:13
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Вот сам экстеншн. Пример для наглядности ниже


Код ок, все мелочи вроде соблюдены, насколько помню.
Но после появления await я в подобных хелперах особого смысла не вижу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.