簡體   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