C#Async,为什么我们需要“保持”控制台以获得异步结果?

时间:2018-02-15 17:54:47

标签: c# asynchronous async-await

在过去的几天里,我一直试图弄清楚为什么我的异步方法不起作用,而且它是一段非常简单的代码。

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应该自己解决的问题之一,而是它的名字暗示的那种问题。 我理解的方式是:

  • Task方法开始在后台执行
  • 我们在async方法
  • 中继续使用3个ConsoleWritelines
  • 由于没有别的事可做而且任务还没有完成,我们到达await行,我们应该等待完成任务 完成后再继续使用其余代码。

只有在中间有另一段代码需要比执​​行Task方法更长的代码,或者如果我使用Console.ReadLine()并且我无法找到关于此的解释时,它的工作原理如此!

我还有一个关于我的实现语法的次要问题。这是创建Task方法的正确方法吗?使用

public Task<T> SomeMethodName(some, args)
{
    return Task<T>Factory.StartNew(() => 
    { 
        somecode that returns T;
    }); 
}

1 个答案:

答案 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作为快捷方式,有关详细信息,请参阅以下问题: