2011-07-21 23 views
17

使用最新CTP5与异步/等待关键字,我写了一些代码,这显然不能编译:如何编写简单的异步方法?

class Program 
    { 
     public class MyClass 
     { 
      async public Task<int> Test() 
      { 
       var result = await TaskEx.Run(() => 
        { 
         Thread.Sleep(3000); 
         return 3; 
        }); 
       return result; 
      } 
     } 

     static void Main(string[] args) 
     { 
      var myClass = new MyClass(); 

      //The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error ??!! 
      int result = await myClass.Test(); 

      Console.ReadLine(); 
     } 
    } 

什么是‘等待’操作只能在方法中使用或lambda标有”个理由'异步'修饰符错误?“ (我选择了Visual Studio指向的行)

回答

8

我不知道您是否可以将Main标记为异步,但是您需要在使用await的任何方法的声明中包含async关键字。例如:

public async void DoStuffAsync() 
{ 
    var myClass = new MyClass(); 

    int result = await myClass.TestAsync(); 
} 
+1

*您可以*'声明作为Main''async'和'await'ing了什么东西* *会结束你的程序 – dlev

+0

(假设你没有其他前台线程运行。)杜,我一直在想,这个错误在我的测试方法中。 Visual Studio应该对这个错误提供更多信息(比如“方法Main must async”) – ghord

+8

在C#5版本中,如果将Main标记为async,则会出现以下错误:“入口点不能用'async 'modifier“ – Anthony

4

await是不一样的Wait();做一个await是该方法的一个重要的重写,特别是影响该方法如何退出给调用者的期望。除非告诉编译器启用一些事情(如unsafe,checkedunchecked,如果你仔细想一想),但是请考虑:这实际上并不是实际的做做多(警告:返回类型)问题巨大在你的例子。如果Main()退出(并且我们假设没有其他线程) - 您执行是烤面包。不见了。不复存在。添加async使您认为仅仅因为退出并不意味着它已完成完成。准备好之前,您确实不希望Main()退出。

作为第二个效果,此开关还形式化该方法只能返回像Task;如果没有这个开关,你可能会试图在以后使它成为异步,这可能是一个重大的突破性改变。

+2

这是一个* ex *程序。 – dlev

+0

@dlev nice Monty Python there; p –

3

异步方法可以有返回类型的void或Task。如果返回类型不是void,则调用者仍然可以使用Main入口方法内的.Net 4中引入的标准Wait机制(不能标记为异步)。这里有一个简单的例子:

static void Main(string[] args) 
    { 
     string address = "http://api.worldbank.org/countries?format=json"; 
     Task t = LoadJsonAsync(address); 
     // do other work while loading 
     t.Wait(); 

     Console.WriteLine("Hit ENTER to exit..."); 
     Console.ReadLine(); 
    } 

    private async static Task LoadJsonAsync(string address) 
    { 
     HttpClient client = new HttpClient(); 

     HttpResponseMessage response = await client.GetAsync(address); 

     // Check that response was successful or throw exception 
     response.EnsureSuccessStatusCode(); 

     // Read response asynchronously as JsonValue and write out top facts for each country 
     JsonArray readTask = await response.Content.ReadAsAsync<JsonArray>(); 
     Console.WriteLine("First 50 countries listed by The World Bank..."); 
     foreach (var country in readTask[1]) 
     { 
      Console.WriteLine(" {0}, Capital: {1}", 
       country.Value["name"], 
       country.Value["capitalCity"]); 
     } 

    } 
+23

我讨厌大家总是如何使用client.GetAsync作为例子。海报可能知道如何使用别人的异步方法。你怎么写*一个? (例如使用睡眠示例) – Jeff

+0

如果异步任务返回结果会怎么样?调用task.wait返回一个布尔值。你将如何去等待,然后使用返回的结果?编辑:没关系。 'Task.Result'。 – Kyle

+0

不确定,但是您是否需要在Wait()之前启动任务t? 't.Start(); t.Wait();' – Prokurors