所以我正在尝试学习在C#中使用'async'和'await'的基础知识,但我不确定我在这里做错了什么。我期待以下输出:
Calling DoDownload
DoDownload done
[...output here...]
但我没有得到下载的输出,我也期望“完成”,但这需要一段时间。不应该立即输出吗?另外,我似乎也无法获得字符串结果。这是我的代码:
namespace AsyncTest
{
class Program
{
static void Main(string[] args)
{
Debug.WriteLine("Calling DoDownload");
DoDownloadAsync();
Debug.WriteLine("DoDownload done");
}
private static async void DoDownloadAsync()
{
WebClient w = new WebClient();
string txt = await w.DownloadStringTaskAsync("http://www.google.com/");
Debug.WriteLine(txt);
}
}
}
答案 0 :(得分:6)
要获得所需的行为,您需要在退出Main()
之前等待该过程完成。为了能够判断您的流程何时完成,您需要从函数返回Task
而不是void
,除非void
函数返回async
,否则你正在处理活动。
正确运行的程序的重写版本将是
class Program
{
static void Main(string[] args)
{
Debug.WriteLine("Calling DoDownload");
var downloadTask = DoDownloadAsync();
Debug.WriteLine("DoDownload done");
downloadTask.Wait(); //Waits for the background task to complete before finishing.
}
private static async Task DoDownloadAsync()
{
WebClient w = new WebClient();
string txt = await w.DownloadStringTaskAsync("http://www.google.com/");
Debug.WriteLine(txt);
}
}
因为await
中的Main()
{}不能await downloadTask;
我必须执行Wait()
功能。如果这是一个SynchronizationContext {{}}}的应用程序,我会改为async
并执行此功能,这是从{{1}}调用的。
答案 1 :(得分:3)
您正在调用DoDownloadAsync()但不等待它。所以你的程序将进入下一行。但是还有另外一个问题,Async方法应该返回Task
或Task<T>
,如果你什么也没有返回,并且你希望你的方法是异步运行的,你应该像这样定义你的方法:
private static async Task DoDownloadAsync()
{
WebClient w = new WebClient();
string txt = await w.DownloadStringTaskAsync("http://www.google.com/");
Debug.WriteLine(txt);
}
在Main方法中,您无法等待DoDownloadAsync
,因为您无法在非异步函数中使用await关键字,并且无法使Main
异步。所以考虑一下:
var result = DoDownloadAsync();
Debug.WriteLine("DoDownload done");
result.Wait();