当前位置:  开发笔记 > 编程语言 > 正文

等待WebClient.DownloadStringTaskAsync永远等待,但访问Result属性工作

如何解决《等待WebClient.DownloadStringTaskAsync永远等待,但访问Result属性工作》经验,为你挑选了1个好方法。

以下代码正常工作(在控制台上打印标记):

System.Net.WebClient wc = new System.Net.WebClient();
var task1 = wc.DownloadStringTaskAsync("https://www.google.com.au");
Console.WriteLine(task1.Result); // works

但是,当我等待任务时,它只是等待永远,任务的状态是WaitingForActivation:

System.Net.WebClient wc = new System.Net.WebClient();
var task1 = wc.DownloadStringTaskAsync("https://www.google.com.au");
Console.WriteLine(await task1);
Console.WriteLine("done!"); // this never gets printed

我错过了什么?

编辑:完整代码:

static void Main(string[] args)
{
    DoIt(); 
}

static async void DoIt()
{
    System.Net.WebClient wc = new System.Net.WebClient();
    var task1 = wc.DownloadStringTaskAsync("https://www.google.com.au");
    Console.WriteLine(await task1);
    Console.WriteLine("done!"); // this never gets printed
}

Yuval Itzcha.. 5

我错过了什么?

目前,您调用代码的方式,我认为无法完成任务WaitingForActivation.一旦DoIt命中第一个await,它就会将控制权交还给调用者,这是你的Main方法,它应该终止并关闭你的控制台.

使用Task.Result是因为它同步阻止异步方法,因此它等待它完成,你看到结果打印到控制台.

你真正需要做的是DoIt async Task代替async void,并Task.Wait在那里使用同步阻止,所以Main不会终止:

static void Main(string[] args)
{
    DoItAsync().Wait(); 
}

static async Task DoItAsync()
{
    System.Net.WebClient wc = new System.Net.WebClient();
    var task1 = wc.DownloadStringTaskAsync("https://www.google.com.au");
    Console.WriteLine(await task1);
    Console.WriteLine("done!"); // this never gets printed
}

注意使用Task.ResultTask.Wait仅用于使控制台不终止.在任何其他环境(UI基于或ASP.NET),你不应该永远阻塞异步代码,应始终await对异步方法.



1> Yuval Itzcha..:

我错过了什么?

目前,您调用代码的方式,我认为无法完成任务WaitingForActivation.一旦DoIt命中第一个await,它就会将控制权交还给调用者,这是你的Main方法,它应该终止并关闭你的控制台.

使用Task.Result是因为它同步阻止异步方法,因此它等待它完成,你看到结果打印到控制台.

你真正需要做的是DoIt async Task代替async void,并Task.Wait在那里使用同步阻止,所以Main不会终止:

static void Main(string[] args)
{
    DoItAsync().Wait(); 
}

static async Task DoItAsync()
{
    System.Net.WebClient wc = new System.Net.WebClient();
    var task1 = wc.DownloadStringTaskAsync("https://www.google.com.au");
    Console.WriteLine(await task1);
    Console.WriteLine("done!"); // this never gets printed
}

注意使用Task.ResultTask.Wait仅用于使控制台不终止.在任何其他环境(UI基于或ASP.NET),你不应该永远阻塞异步代码,应始终await对异步方法.


@Abhinav是的,因为那块"Main"也是:).但是,建议的做法是始终从异步方法返回一个`Task`或`Task `,即使你使用一个简单的控制台应用程序,我认为最好遵循这个方法,从而使`Console.ReadLine`变得多余.
推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有