Где находится WebClient.DownloadStringTaskAsync (Uri, CancellationToken) в VS11 - PullRequest
3 голосов
/ 17 марта 2012

В Async CTP есть метод расширения с подписью

WebClient.DownloadStringTaskAsync(Uri,CancellationToken) 

Где это в VS11?
Нужно ли устанавливать Async CTP, чтобы получить этот метод?

Ответы [ 4 ]

3 голосов
/ 17 марта 2012

В .NET 4.5 вы, вероятно, будете использовать новый класс HttpClient , в частности метод GetStringAsync .

2 голосов
/ 24 июня 2016

К сожалению, поддержка CancellationToken не встроена, но вот как вы можете приблизить ее, используя методы Register и CancelAsync:

var downloadTask = webClient.DownloadStringTaskAsync(source);

string text;
using (cancellationToken.Register(() => webClient.CancelAsync()))
{
    text = await downloadTask;
}
1 голос
/ 17 марта 2012

Он все еще присутствует в бета-версии .Net 4.5, см. MSDN , за исключением того, что он больше не является методом расширения.

То, на что вы можете ссылаться, это тот факт, что WebClientвключены в .Net для приложений в стиле Metro.Там вы, вероятно, должны использовать HttpClient.Другой вариант - использовать HttpWebRequest, который все еще присутствует и расширен также с помощью Task асинхронных методов.

0 голосов
/ 10 июля 2015

Оба класса System.Net.WebClient и System.Net.Http.HttpClient имеют асинхронную функцию. Это позволяет вам создать асинхронную функцию. Пока функция GetStringAsync работает асинхронно, вы можете регулярно проверять, запрашивается ли отмена.

Пример: используя System.Net.Http; класс HttpSonnetFetcher { const string sonnetsShakespeare = @ "http://www.gutenberg.org/cache/epub/1041/pg1041.txt";

    public async Task<IEnumerable<string>> Fetch(CancellationToken token)
    {
        string bookShakespeareSonnets = null;
        using (var downloader = new HttpClient())
        {
            var downloadTask = downloader.GetStringAsync(sonnetsShakespeare);
            // wait until downloadTask finished, but regularly check if cancellation requested:
            while (!downloadTask.Wait(TimeSpan.FromSeconds(0.2)))
            {
                token.ThrowIfCancellationRequested();
            }
            // if still here: downloadTask completed
            bookShakespeareSonnets = downloadTask.Result;
        }

        // just for fun: find a nice sonnet, remove the beginning, split into lines and return 12 lines
        var indexNiceSonnet = bookShakespeareSonnets.IndexOf("Shall I compare thee to a summer's day?");
        return bookShakespeareSonnets.Remove(0, indexNiceSonnet)
            .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Take(12);  
    }
}

Использование будет следующим:

private void TestCancellationHttpClient()
{
    try
    {
        var sonnetFetcher = new HttpSonnetFetcher();
        var cancellationTokenSource = new CancellationTokenSource();

        var sonnetTask = Task.Run(() => sonnetFetcher.Fetch(cancellationTokenSource.Token));
        cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10));

        // meanwhile do something else, checking regularly if the task finished, or if you have nothing to do, just Task.Wait():
        while (!sonnetTask.Wait(TimeSpan.FromSeconds(0.25)))
        {
            Console.Write('.');
        }
        // if still here: the sonnet is fetched. return value is in sonnetTask.Result
        Console.WriteLine("A nice sonnet by William Shakespeare:");
        foreach (var line in sonnetTask.Result)
        {
            Console.WriteLine(line);
        }
    }

    catch (OperationCanceledException exc)
    {
        Console.WriteLine("Canceled " + exc.Message);
    }
    catch (AggregateException exc)
    {
        Console.WriteLine("Task reports exceptions");
        var x = exc.Flatten();
        foreach (var innerException in x.InnerExceptions)
        {
            Console.WriteLine(innerException.Message);
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine("Exception: " + exc.Message);
    }
}

Попробуйте сделать это в простой консольной программе и убедитесь, что сонет получен правильно, уменьшите значение CancelAfter с 10 секунд, скажем, до 0,1 секунды, и убедитесь, что задача правильно отменена.

Примечание: хотя выдается исключение OperationCancelledException, это исключение рассматривается как внутреннее исключение AggregateException. Все исключения, возникающие в рамках задачи, всегда заключаются в AggregateException.

...