异步在 C# 中的控制台应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17630506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:04:30  来源:igfitidea点击:

async at console app in C#?

c#.net-4.5async-awaitc#-5.0

提问by Royi Namir

I have this simple code :

我有这个简单的代码:

public static async Task<int> SumTwoOperationsAsync()
{
    var firstTask = GetOperationOneAsync();
    var secondTask = GetOperationTwoAsync();
    return await firstTask + await secondTask;
}


private async Task<int> GetOperationOneAsync()
{
    await Task.Delay(500); // Just to simulate an operation taking time
    return 10;
}

private async Task<int> GetOperationTwoAsync()
{
    await Task.Delay(100); // Just to simulate an operation taking time
    return 5;
}

Great. this compiles.

伟大的。这编译。

But Lets say I have a console app and I want to run the code above ( calling SumTwoOperationsAsync())

但是假设我有一个控制台应用程序,我想运行上面的代码(调用SumTwoOperationsAsync()

 static  void Main(string[] args)
        {
             SumTwoOperationsAsync();
        }

But I've read that (when using sync) I have to sync all the way upand down:

但我读过,(使用时sync)我对所有同步的方式向上向下

Question: So does this means that my Mainfunction should be marked as async?

问题:那么这是否意味着我的Main函数应该被标记为async

Well it can'tbe because there is a compilation error:

好吧,不可能是因为存在编译错误:

an entry point cannot be marked with the 'async' modifier

入口点不能用“async”修饰符标记

If I understand the async stuff , the thread will enter the Mainfunction ----> SumTwoOperationsAsync---->will call both functions and will be out. but until the SumTwoOperationsAsync

如果我理解异步的东西,线程将进入Main函数 ----> SumTwoOperationsAsync----> 将调用两个函数并退出。但直到SumTwoOperationsAsync

What am I missing ?

我错过了什么?

采纳答案by Stephen Cleary

In most project types, your async"up" and "down" will end at an async voidevent handler or returning a Taskto your framework.

在大多数项目类型中,您的async“向上”和“向下”将在async void事件处理程序处结束或将 a 返回Task到您的框架。

However, Console apps do not support this.

但是,控制台应用程序不支持此功能。

You can either just do a Waiton the returned task:

您可以只Wait对返回的任务执行以下操作:

static void Main()
{
  MainAsync().Wait();
  // or, if you want to avoid exceptions being wrapped into AggregateException:
  //  MainAsync().GetAwaiter().GetResult();
}

static async Task MainAsync()
{
  ...
}

or you can use your own context like the one I wrote:

或者你可以像我写的那样使用你自己的上下文

static void Main()
{
  AsyncContext.Run(() => MainAsync());
}

static async Task MainAsync()
{
  ...
}

More information for asyncConsole apps is on my blog.

async控制台应用程序的更多信息在我的博客上

回答by Murilo Maciel Curti

Here is the simplest way to do this

这是执行此操作的最简单方法

static void Main(string[] args)
{
    Task t = MainAsync(args);
    t.Wait();
}

static async Task MainAsync(string[] args)
{
    await ...
}

回答by Alberto

As a quick and very scoped solution:

作为一个快速且范围广泛的解决方案:

Task.Result

任务.结果

Both Task.Result and Task.Wait won't allow to improving scalability when used with I/O, as they will cause the calling thread to stay blocked waiting for the I/O to end.

Task.Result 和 Task.Wait 在与 I/O 一起使用时都不允许提高可伸缩性,因为它们会导致调用线程保持阻塞等待 I/O 结束。

When you call .Result on an incomplete Task, the thread executing the method has to sit and wait for the task to complete, which blocks the thread from doing any other useful work in the meantime. This negates the benefit of the asynchronous nature of the task.

当您在未完成的任务上调用 .Result 时,执行该方法的线程必须坐下来等待任务完成,这会阻止线程在此期间执行任何其他有用的工作。这否定了任务异步性质的好处。

notasync

不同步

回答by Richard Keene

My solution. The JSONServer is a class I wrote for running an HttpListener server in a console window.

我的解决方案。JSONServer 是我为在控制台窗口中运行 HttpListener 服务器而编写的类。

class Program
{
    public static JSONServer srv = null;

    static void Main(string[] args)
    {
        Console.WriteLine("NLPS Core Server");

        srv = new JSONServer(100);
        srv.Start();

        InputLoopProcessor();

        while(srv.IsRunning)
        {
            Thread.Sleep(250);
        }

    }

    private static async Task InputLoopProcessor()
    {
        string line = "";

        Console.WriteLine("Core NLPS Server: Started on port 8080. " + DateTime.Now);

        while(line != "quit")
        {
            Console.Write(": ");
            line = Console.ReadLine().ToLower();
            Console.WriteLine(line);

            if(line == "?" || line == "help")
            {
                Console.WriteLine("Core NLPS Server Help");
                Console.WriteLine("    ? or help: Show this help.");
                Console.WriteLine("    quit: Stop the server.");
            }
        }
        srv.Stop();
        Console.WriteLine("Core Processor done at " + DateTime.Now);

    }
}