在过去的几天里,我一直试图弄清楚为什么我的异步方法不起作用,而且它是一段非常简单的代码。
public class EntryPoint
{
static void Main()
{
RunTheTaskAsync();
//Console.ReadLine(); // if I add this to "hold" the finish of the project, I will see the result, without it I dont
}
public async static void RunTheTaskAsync()
{
Task<string> task = Concatenator('1', 200000);
Console.WriteLine("Heeeelllooooooo");
Console.WriteLine("I am running while Concatenator is concatenating in the background.");
Console.WriteLine("You will receive the results shortly");
string result = await task;
Console.WriteLine("Result is: " + result.Length);
}
public static Task<string> Concatenator(char characterToConcatenate, int count)
{
Console.WriteLine("Concatenating!");
return Task<string>.Factory.StartNew(() =>
{
string concatenatedString = "";
for (int i = 0; i < count; i++)
{
concatenatedString += characterToConcatenate;
}
return concatenatedString;
});
}
}
如果我在上面的示例中运行它,我永远不会看到结果,我只看到Console.WriteLine并按任意键继续..之后没有结果。
如果我取消注释Console.ReadLine();一切正常,因为我期待它的工作,我简直无法理解为什么!?!如果我添加一些Thread.Sleep(xxx)或另一段需要比“Concatenator”方法执行时间更长的代码,情况也是如此。
这不是await
应该自己解决的问题之一,而是它的名字暗示的那种问题。
我理解的方式是:
await
行,我们应该等待完成任务
完成后再继续使用其余代码。只有在中间有另一段代码需要比执行Task方法更长的代码,或者如果我使用Console.ReadLine()并且我无法找到关于此的解释时,它的工作原理如此!
我还有一个关于我的实现语法的次要问题。这是创建Task方法的正确方法吗?使用
public Task<T> SomeMethodName(some, args)
{
return Task<T>Factory.StartNew(() =>
{
somecode that returns T;
});
}
答案 0 :(得分:4)
async void
s(就像您的RunTheTaskAsync
方法一样)是&#34;开火并忘记&#34;。您无法跟踪他们的进度,也几乎不想使用它们。
相反,请创建async Task
并等待它:
static async Task Main()
{
await RunTheTaskAsync();
}
public static async Task RunTheTaskAsync()
{
...
}
有关详细信息,请参阅:
注意:2017 Update 3之前的Visual Studio不支持async Main
方法。在这种情况下,您必须manually await the Task:
static void Main()
{
RunTheTaskAsync().GetAwaiter().Wait();
}
关于你的第二个问题(未来:SO&#39的策略是&#34;每个问题一个问题&#34;):是的,Task.Factory.StartNew
是正确的,如果你需要你的任务在单独的线程。较新版本的.NET提供Task.Run
作为快捷方式,有关详细信息,请参阅以下问题: