在异步 CTP 中有一个带有签名的扩展方法
WebClient.DownloadStringTaskAsync(Uri,CancellationToken)
这是在VS11中的什么地方?
我是否需要安装 Async CTP 才能使用此方法?
在异步 CTP 中有一个带有签名的扩展方法
WebClient.DownloadStringTaskAsync(Uri,CancellationToken)
这是在VS11中的什么地方?
我是否需要安装 Async CTP 才能使用此方法?
在 .NET 4.5 中,您可能会使用新的HttpClient Class,尤其是GetStringAsync Method。
不幸的是 CancellationToken 支持不是内置的,但这里是您可以通过利用 Register 和 CancelAsync 方法来近似它的方法:
var downloadTask = webClient.DownloadStringTaskAsync(source);
string text;
using (cancellationToken.Register(() => webClient.CancelAsync()))
{
text = await downloadTask;
}
它仍然存在于 .Net 4.5 beta 中,请参阅MSDN,但它不再是扩展方法。
您可能指的是WebClient
.Net 中不包含 Metro 风格应用程序的事实。在那里,您可能应该使用HttpClient
. 另一种选择是使用HttpWebRequest
,它仍然存在,并且也使用Task
基于 - 的异步方法进行了扩展。
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 中。