刚拿到 VS2012 并试图掌握async
.
假设我有一个从阻塞源获取一些值的方法。我不希望方法的调用者阻塞。我可以编写方法来获取值到达时调用的回调,但由于我使用的是 C# 5,我决定使方法异步,因此调用者不必处理回调:
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
这是一个调用它的示例方法。如果PromptForStringAsync
不是异步的,则此方法需要在回调中嵌套回调。使用异步,我可以以这种非常自然的方式编写我的方法:
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
到现在为止还挺好。问题是当我调用GetNameAsync 时:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
的全部意义GetNameAsync
在于它是异步的。我不想让它阻塞,因为我想尽快回到 MainWorkOfApplicationIDontWantBlocked 并让 GetNameAsync 在后台做它的事情。但是,以这种方式调用它会给我一个编译器警告GetNameAsync
:
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
我完全知道“在调用完成之前继续执行当前方法”。这就是异步代码的重点,对吧?
我更喜欢在没有警告的情况下编译我的代码,但这里没有什么可以“修复”的,因为代码正在做我打算做的事情。我可以通过存储返回值来消除警告GetNameAsync
:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
但现在我有多余的代码。Visual Studio 似乎明白我被迫编写这个不必要的代码,因为它抑制了正常的“从未使用的值”警告。
我还可以通过将 GetNameAsync 包装在非异步方法中来消除警告:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
但那是更多余的代码。所以我必须编写不需要或容忍不必要警告的代码。
我在这里使用 async 有什么问题吗?