当前位置: 首页 > 编程语言 > C#

为什么WebClient.DownloadStringTaskAsync()会阻塞?–新的异步API-语法-CTP共享

时间:2023-04-11 10:53:30 C#

为什么WebClient.DownloadStringTaskAsync()会阻塞?-新的异步API/语法/CTP由于某种原因,它在下面的程序启动后挂起。我相信WebClient().DownloadStringTaskAsync()是原因。类程序{staticvoidMain(string[]args){AsyncReturnTask();对于(inti=0;i<15;i++){Console.WriteLine(i);线程.睡眠(100);}}publicstaticasyncvoidAsyncReturnTask(){varresult=awaitDownloadAndReturnTaskStringAsync();控制台.WriteLine(结果);}privatestaticasyncTaskDownloadAndReturnTaskStringAsync(){returnawaitnewWebClient().DownloadStringTaskAsync(newUri("http://www.weather.gov"));据我所知,我的程序应该立即开始从0到15计数。我做错了什么吗?我在原始Netflix下载示例(使用CTP获得)中遇到了同样的问题——按下搜索按钮后,用户界面首先冻结——过了一会儿,它在加载下一部电影时做出响应。我相信它并没有冻结AndersHejlsberg在PDC2010上的演讲。还有一件事。而不是returnawaitnewWebClient().DownloadStringTaskAsync(newUri("http://www.weather.gov"));我使用自己的方法:returnawaitReturnOrdinaryTask();这是:publicstaticTaskReturnOrdinaryTask(){vart=Task.Factory.StartNew(()=>{for(inti=0;i<10;i++){Console.WriteLine("-------------"+i.ToString());Thread.Sleep(100);}return"sometext";});返回吨;它应该工作。我的意思是它不加载任何东西,但它会立即启动并且在工作时不会阻塞主线程。编辑好的,这就是我现在相信的:WebClient.DownloadStringTaskAsync函数被搞砸了。它应该在没有初始阻塞期的情况下工作,如下所示:staticvoidMain(string[]args){WebClientcli=newWebClient();Task.Factory.StartNew(()=>{cli.DownloadStringCompleted+=(sender,e)=>Console.WriteLine(e.Result);cli.DownloadStringAsync(newUri("http://www.weather.gov"));});对于(inti=0;i<100;i++){Console.WriteLine(i);线程.睡眠(100);当您的程序暂时阻塞时,它会在从远程服务器返回结果之前在for循环中恢复执行。请记住,新的异步API仍然是单线程的。因此,WebClient().DownloadStringTaskAsync()仍然需要在您的线程上运行,直到请求准备好并发送到服务器,然后它才能等待并返回到Main()中的程序流执行。我认为您看到的结果是因为从您的计算机创建和发出请求需要一些时间。首先,完成后,您的DownloadStringTaskAsync实现可以等待网络IO和远程服务器完成,然后可以将执行返回给您。另一方面,RunOrdinaryTask方法只是初始化任务并为其提供工作负载并告诉它开始。然后它立即返回。那就是使用RunOrdinaryTask时看不到延迟的RunOrdinaryTask。以下是有关该主题的一些链接:EricLippert的博客(语言设计者之一)和JonSkeet的原始博客文章。Eric有一系列关于延续传递风格的5篇文章,这实际上就是async和await的真正含义。如果您想了解有关新功能的更多信息,您可能需要阅读Eric关于CPS和异步的帖子。无论如何,上面的两个链接都很好地解释了一个非常重要的事实:换句话说,async和await不会为您启动一个新线程。当你有阻塞操作时,它们只允许你恢复正常流程的执行——你的CPU将在同步程序中闲置一段时间,等待一些外部操作完成。编辑只是为了弄清楚发生了什么:DownloadStringTaskAsync设置了一个延续,然后在同一线程上调用WebClient.DownloadStringAsync,然后将执行返回到您的代码。因此,在循环开始计数之前看到的阻塞时间就是DownloadStringAsync完成所需的时间。您的带有async和await的程序与以下程序非常接近,它表现出与该程序相同的行为:初始块,然后开始计数,在中间的某个地方,异步操作完成并打印程序从中请求的url:staticvoidMain(string[]args){WebClientcli=newWebClient();cli.DownloadStringCompleted+=(sender,e)=>Console.WriteLine(e.Result);cli.DownloadStringAsync(newUri("http://www.weather.gov"));//Blocksuntilrequesthasbeenpreparedfor(inti=0;i注意:我绝不是这方面的专家,所以我在某些点上可能是错误的。如果你认为这是一个错误是的,请随时纠正我对这个话题的理解——我昨晚刚刚看了PDC演示并玩了CTP。你确定问题与从IE/Registry/SomewhereSlow检测到的代理配置设置无关吗?尝试设置webClient.Proxy=null(或指定asettinginapp.config),andthe"blocking"periodshouldbeminimum.DoyoupressF5orCTLR+F5torun?F5,VSjustsearchesforAsyncCtpLibrary.dllNotationanddelay...以上是C#学习教程:WebClient.DownloadStringTaskAsync()为什么会阻塞?-新的异步API/语法/CTP分享所有内容,如果对大家有用需要了解更多C#学习教程,希望大家关注---本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如有转载请注明出处: