繁体   English   中英

为什么async / await在我的ASP.net 5控制台应用程序中不起作用?

[英]Why is async/await not working in my ASP.net 5 Console Application?

我在Windows(.NET 4.5.1)和Linux(Mono 4.0.1)上尝试了这个简单的ASP.net 5控制台应用程序,两次都有相同的结果。

注意:我将其称为ASP.net 5控制台应用程序,因为这是在Visual Studio中调用到RC的内容。 现在它被称为控制台应用程序(包),但它仍然使用来自https://github.com/aspnet/dnx的 DNX :)

我的Program.cs

using System;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    public class Program
    {
        public async void Main(String[] args)
        {
            #if DNX451
            AppDomain.CurrentDomain.UnhandledException += 
                (s, e) => Console.WriteLine(e);
            #endif

            try
            {
                await Task.Delay(1000);
                Console.WriteLine("After Task.Delay");
            }
            finally
            {
                Console.WriteLine("Inside Finally");
            }
        }
    }
}

我的project.json

{
    "version": "1.0.0-*",
    "dependencies": {},
    "commands": {
        "ConsoleApplication": "ConsoleApplication"
    },
    "frameworks": {
        "dnx451": {}
    }
}

当与任一运行1.0.0-beta4 CLR1.0.0-beta5-11904 CLR ,命令dnx . ConsoleApplication dnx . ConsoleApplication什么都不打印。 一旦遇到Task.Delay ,程序将以状态码0退出。 即使是finally块也永远不会执行。

我无法测试.NET Core 5.0,因为dnu restore表示一切正常,但运行时无法找到包。 那好吧...

有没有人对async / await和DNX有同样的问题? 或者发现我犯的一些错误?

如果您在入口点看到我的问题(和答案), 可以使用CoreCLR上的'async'修饰符进行标记? ,你会看到在最顶层的调用堆栈中,你有以下内容:

public static int Execute(string[] args)
{
    // If we're a console host then print exceptions to stderr
    var printExceptionsToStdError = Environment
                                    .GetEnvironmentVariable
                                     (EnvironmentNames.ConsoleHost) == "1";

    try
    {
        return ExecuteAsync(args).GetAwaiter().GetResult();
    }
    catch (Exception ex)
    {
        if (printExceptionsToStdError)
        {
            PrintErrors(ex);
            return 1;
        }

        throw;
    }
}

在内部,它检查以查看方法的返回类型,如果返回类型是Task类型,则它会注册一个ContinueWith ,它将能够同步等待:

if (result is Task)
{
    return ((Task)result).ContinueWith(t =>
    {
        return 0;
    });
}

当你传入async void ,它会查找Execute ,好像这个方法是一个“fire and forget”void返回方法。 这就是它永远不会完成执行的原因。 但是,如果你改变它以返回一个Task ,它将工作:

public async Task Main(String[] args)
{
    #if DNX451
    AppDomain.CurrentDomain.UnhandledException += 
        (s, e) => Console.WriteLine(e);
    #endif

    try
    {
        await Task.Delay(1000);
        Console.WriteLine("After Task.Delay");
    }
    finally
    {
        Console.WriteLine("Inside Finally");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM