问题
Using latest CTP5 with async/await keywords, I wrote some code, which apparently cannot compile:
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();
}
}
What is th reason of "The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error?" (I've selected the line which Visual Studio point me to)
回答1:
I don't know if you can mark Main as async, but you need to include the async
keyword in the declaration of any method that uses await
. For example:
public async void DoStuffAsync ()
{
var myClass = new MyClass ();
int result = await myClass.TestAsync ();
}
回答2:
await
is not the same as Wait()
; doing an await
is a significant re-writing of that method, and in particular affects the expectation of how that method exits to the caller. You are right in that it doesn't actually do much (caveat: return types) except tell the compiler to enable some things (as do switches like unsafe
, checked
and unchecked
if you think about it) - but consider: this actually matters hugely in your example. If Main()
exits (and we assume no other threads) - you exe is toast. Gone. No longer exists. Adding async
makes you consider that just because the method exits doesn't mean it has finished. You really don't want Main()
exiting before you are ready.
As a secondary effect, this switch also formalises that the method can only return things like Task
; without the switch, you might be tempted to make it async later, which could be a significantly breaking change.
回答3:
An async method can have a return type of void or Task. If the return type is not void the caller can still use the standard Wait mechanism introduced in .Net 4 inside the Main entry method (which can not be marked async). Here's a simple example:
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"]);
}
}
来源:https://stackoverflow.com/questions/6772789/how-to-write-simple-async-method