【发布时间】:2018-02-16 19:42:59
【问题描述】:
在过去的几天里,我一直在试图弄清楚为什么我的异步方法不起作用以及它是一段非常简单的代码。
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) 或另一段比“连接器”方法执行时间更长的代码,情况也是如此。
这不是await 应该自行解决的问题之一吗,它的名字就暗示了这一点。
我的理解是:
- Task 方法开始在后台执行
- 我们继续使用异步方法中的 3 个 ConsoleWritelines
- 由于没有其他事情可做,任务还没有完成,我们到达
await这一行,我们应该等待任务 完成,然后继续执行其余代码。
只有在中间有另一段代码比 Task 方法需要更长的时间才能执行,或者如果我使用 Console.ReadLine() 并且我找不到关于此的解释时,它才会像这样工作!
我还有一个关于我的实现语法的次要问题。这是创建任务方法的正确方法吗?通过使用
public Task<T> SomeMethodName(some, args)
{
return Task<T>Factory.StartNew(() =>
{
somecode that returns T;
});
}
【问题讨论】:
-
您不应该 `await RunTheTaskAsync();` 以防止 Main 在 RunTheTaskAsync 完成之前返回吗?
-
澄清一下 - 你的问题是“为什么我在操作完成之前结束进程我没有得到操作结果?”
-
RunTheTaskAsync()也需要返回Task,而不是void。 -
为什么会被否决?这是一个明确、具体的问题,甚至包括一个 mcve。
-
这里更根本的问题是:您试图从控制台应用程序中了解异步代码是如何工作的。这是个坏主意。编写一个 GUI 应用程序并使其异步; GUI 从一开始就被设计为支持异步工作流,因为它们有一个消息循环。
标签: c# asynchronous async-await