为什么Web客户端.DownloadStringTaskAsync()块?-新的异步API/法/CTP
-
27-09-2019 - |
题
对于一些原因,是暂停程序之后下面开始。我相信, WebClient().DownloadStringTaskAsync()
是原因。
class Program
{
static void Main(string[] args)
{
AsyncReturnTask();
for (int i = 0; i < 15; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
public static async void AsyncReturnTask()
{
var result = await DownloadAndReturnTaskStringAsync();
Console.WriteLine(result);
}
private static async Task<string> DownloadAndReturnTaskStringAsync()
{
return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
}
}
因为我了解我的程序应该开始计数,从0至15。我做错了什么?
我有同样的问题与原有的Netflix下载的样本(这你得到 CTP)-然后按下搜索键UI第一个冻结和一段时间后,这是响应,同时loadning下电影。我相信这没有冻结在安德斯*Hejlsberg的介绍在PDC2010年。
有一件事。当而不是的
return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
我用我自己的方法:
return await ReturnOrdinaryTask();
这是:
public static Task<string> ReturnOrdinaryTask()
{
var t = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("------------- " + i.ToString());
Thread.Sleep(100);
}
return "some text";
});
return t;
}
它可以作为这是应该的。我的意思是它不负载任何东西,但它立即开始并不框主线,而这样做其工作。
编辑
OK,我认为现在是:的 WebClient.DownloadStringTaskAsync
功能是搞砸了。它应当工作没有最初的阻挡期,这样的:
static void Main(string[] args)
{
WebClient cli = new WebClient();
Task.Factory.StartNew(() =>
{
cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
cli.DownloadStringAsync(new Uri("http://www.weather.gov"));
});
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
解决方案
而你的节目不会块一段时间,它不会恢复执行在循环之前,结果是返回的远程服务器。
记得,新的异步API仍然是单一的螺纹。所以 WebClient().DownloadStringTaskAsync()
仍然需要运行在线直到的请求已经编制并发送到服务器之前,它可以 await
和产量执行回到你的程序流程中主要的().
我觉得您所看到的结果是由于这样的事实,它需要一些时间来创建并发送该请求从你的机器。第一次时,已经完成,执行 DownloadStringTaskAsync
可以等待网络IO和远程服务器完成,并且可以返回的执行。
另一方面,你 RunOrdinaryTask
方法只是初始化的任务,并赋予它一个工作量,以及告诉它来开始。然后,它立即返回。这就是为什么你没有看到一个延迟的时候使用 RunOrdinaryTask
.
这里有一些链接的主题: 埃里克利珀特的博客 (一种语言设计师),以及 Jon双向飞碟的初次博客 关于它。埃里克有一系列的5个员额有关的延续传递的风格,这真的是什么 async
和 await
是真的。如果你想了解的新功能详细,你可能会想读Eric的员额有关CPS和异步.不管怎么说,这两个链接上述不良好的工作月说明一个非常重要的事实:
- 异步!= 平行的
换句话说, async
和 await
不旋新线。他们只是让你继续执行你的正常流动,当你正在做一个阻止运作时间在你的CPU会只是坐在做什么同步的程序,等待对一些外部动作,以完成。
编辑
只是要清楚发生了什么: DownloadStringTaskAsync
设置一个延续,然后电话 WebClient.DownloadStringAsync
, 在同一线, 然后 产量执行回到你的代码。因此,阻挡时间你都看到的以前的循环开始计算,所需的时间 DownloadStringAsync
来完成。你的程序有异步,并等待着非常接近以相当于下列的程序,其表现出同样的行为作为你的计划:最初的方框,然后开始计数,并在中间的某个地方,异步op完成和印刷品内容的请求的URL:
static void Main(string[] args)
{
WebClient cli = new WebClient();
cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
cli.DownloadStringAsync(new Uri("http://www.weather.gov")); // Blocks until request has been prepared
for (int i = 0; i < 15; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
注:我绝不意味着这方面的专家,因此我可能是错的一些要点。随时纠正我的理解该主题,如果你觉得这是错误的-我只是看着PDC介绍,并发挥与CTP的最后一晚。
其他提示
您确定问题是不相关的代理配置设置慢?
尝试设置webClient.Proxy = NULL(或在指定的app.config设置)和 “封闭” 期应该是最小的。
您按F5或CTRL + F5运行呢?借助F5有一个为VS只是来搜索异步Library.dll ...
符号延迟