von*_*dip 16 c# asynchronous task-parallel-library async-await c#-5.0
我是c#5异步功能的新手.我试图理解这两个实现之间的区别:
实施1:
private void Start()
{
foreach(var url in urls)
{
ParseHtml(url);
}
}
private async void ParseHtml(string url)
{
var query = BuildQuery(url); //BuildQuery is some helper method
var html = await DownloadHtml(query);
//...
MyType parsedItem = ParseHtml(html);
SaveTypeToDB(parsedItem);
}
private async Task<string> DownloadHtml(string query)
{
using (var client = new HttpClient())
try
{
var response = await client.GetAsync(query);
return (await response.Content.ReadAsAsync<string>());
}
catch (Exception ex)
{
Logger.Error(msg, ex);
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
实施2:
private void DoLoop()
{
foreach(var url in urls)
{
Start(url);
}
}
private async void Start(url)
{
await Task.Run( () => ParseHtml(url)) ;
}
private void ParseHtml(string url)
{
var query = BuildQuery(url); //BuildQuery is some helper method
var html = DownloadHtml(query);
//...
MyType parsedItem = ParseHtml(html);
SaveTypeToDB(parsedItem);
}
private string DownloadHtml(string query)
{
using (var client = new WebClient())
{
try
{
return client.DownloadString(query);
}
catch (Exception ex)
{
Logger.Error(msg, ex);
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我宁愿使用第二个实现,因为它会在我的代码中对方法需要较少的"异步"签名.我试图了解使用HttpClient类与使用新任务并等待它的好处是什么?
这两种实现有什么区别吗?
Jon*_*eet 28
我宁愿使用第二个实现,因为它会在我的代码中对方法需要较少的"异步"签名.
这听起来像是一个非常奇怪的理由.你试图从根本上"稍微异步"执行 - 那么为什么不明白呢?
这两种实现有什么区别吗?
绝对.第二个实现将在WebClient.DownloadString块时占用一个线程,等待请求完成.第一个版本没有任何阻塞的线程 - 它依赖于在请求完成时触发的延续.
另外,考虑一下你的Logger.Error电话.在异步版本中,它仍将在原始调用代码的上下文中执行.因此,如果它位于Windows窗体UI中,您仍将位于UI线程上,并且您可以访问UI元素等.在第二个版本中,您将在线程池线程中执行,并且需要编组回UI线程以更新UI.
请注意,您的async void方法几乎肯定不应该async void.您应该只为了遵守事件处理程序签名而async返回一个方法void.在所有其他情况下,返回Task- 调用者可以看到您的任务何时完成,处理异常等.
另请注意,您不需要使用HttpClient异步 - 您可以使用WebClient.DownloadStringTaskAsync,因此您的最终方法可能变为:
private async Task<string> DownloadHtml(string query)
{
using (var client = new WebClient())
{
try
{
return await client.DownloadStringTaskAsync(query);
}
catch (Exception ex)
{
Logger.Error(msg, ex);
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于服务器应用程序,async是关于最小化已经阻塞的线程数:提高线程池的效率,并允许您的程序扩展到更多用户.
对于您不太可能需要关心线程计数的客户端应用程序,async提供了一种相对简单的方法,可以在执行I/O时保持UI运行流畅.
它Task.Run与引擎盖下方有很大不同.
| 归档时间: |
|
| 查看次数: |
20612 次 |
| 最近记录: |