1

我正在使用该async框架进行网络通话。我在下面的代码中收到一个错误

class Program
{
    static void Main(string[] args)
    {
        TestAsync async = new TestAsync();
        await async.Go();//Error:  the await operator can only be used with an async method.  Consider markign this method with the async modifier.  Consider applying the await operator to the result of the call
    }
}

class TestAsync
{
    public async Task Go()
    {
        using (WebClient client = new WebClient())
        {
            var myString =  await client.DownloadStringTaskAsync("http://msdn.microsoft.com");
            Console.WriteLine(myString);
        }    
    }
}

我已经尝试了此代码的几种变体。它要么在运行时失败,要么无法编译。在这种情况下,该方法在我的异步调用被允许触发之前完成。我究竟做错了什么?

我的目标是以异步方式使用 WebClient 执行对网站的调用。我想将结果作为字符串返回并使用Console.WriteLine. 如果您从执行的代码开始感觉更舒服,只需更改

await async.Go();toasync.Go();代码将运行,但不会命中 Console.WriteLine。

4

2 回答 2

2

错误消息正确地告诉您await只能在async方法中使用。但是,你不能 make Main() async,C# 不支持。

但是async方法返回Tasks,这与Task自 .Net 4.0 以来在 TPL 中使用的相同。并且Tasks 确实支持使用同步等待Wait()方法。因此,您可以像这样编写代码:

class Program
{
    static void Main(string[] args)
    {
        TestAsync async = new TestAsync();
        async.Go().Wait();
    }
}

在这里使用Wait()是正确的解决方案,但在其他情况下,混合使用同步等待Wait()和异步等待await可能很危险,并且可能导致死锁(尤其是在 GUI 应用程序或 ASP.NET 中)。

于 2012-08-21T20:25:31.693 回答
-1

该程序在 Web 请求完成之前就结束了。这是因为 Main 不会等待异步操作完成,因为它无事可做。

我敢打赌,如果你让 Main 持续更长时间,那么Console.WriteLine就会被跟注。

我会尝试在调用异步方法后添加睡眠Thread.Sleep(500)- 任何足够长的时间以允许 Web 请求完成都应该有效。

于 2012-08-21T20:16:02.800 回答