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

时间:2013-07-13 13:09:57

标签: c# .net-4.5 async-await c#-5.0

我有这个简单的代码:

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;
}

大。这个编译。

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

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

但我已经读过(使用sync时)我必须一直同步向上向下

问题:这是否意味着我的Main功能应标记为async

好吧不能因为有编译错误:

  

无法使用“async”修饰符标记入口点

如果我理解异步内容,则该主题将进入Main函数----&gt; SumTwoOperationsAsync ----&gt;将调用这两个函数并将被删除。但直到SumTwoOperationsAsync

我错过了什么?

4 个答案:

答案 0 :(得分:270)

在大多数项目类型中,async“向上”和“向下”将以async void事件处理程序结束或将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()
{
  ...
}

或者你可以use your own context like the one I wrote

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

static async Task MainAsync()
{
  ...
}

async控制台应用的详细信息为on my blog

答案 1 :(得分:88)

这是最简单的方法

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

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

答案 2 :(得分:2)

作为快速且非常有范围的解决方案:

Task.Result

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

  

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

notasync

答案 3 :(得分:1)

我的解决方案。 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);

    }
}