为什么我的代码在此方案的方法完成之前退出?

时间:2018-03-08 05:12:56

标签: c# .net asp.net-web-api asp.net-web-api2

我有一个调用这样的方法的控制台应用程序:

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

    static async void Test()
    {
        await SyncADToDBAsync();
    }

    static async Task SyncADToDBAsync()
    {
        using (var client = GetHttpClient())
        {
            try
            {
                var action = new { Type = "SyncADToDB", Domains = new string[] { "my.domain" } };
                var response = await client.PostAsJsonAsync("api/v1/active-directory/actions", action);
                response.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                var x = 0;
            }
        }
    }

但是,当我使用client.PostAsJsonAsync()进入代码行时,控制台应用会退出。如何构建代码以便控制台应用程序不会退出,因此控制台应用程序会等待服务返回的值?看起来目标Web API控制器方法没有受到测试调用的影响,尽管当我使用WebClient而不是HttpClient实现调用时,服务方法越来越受欢迎。

1 个答案:

答案 0 :(得分:1)

  

[W] hy是我在此方案完成方法之前退出的代码吗?

代码正在退出,因为虽然SyncADToDBAsync正在等待PostAsJsonAsync完成,而Test正在等待SyncADToDBAsync完成,但Main并未等待Test完成并因此过早退出。

  

如何构建代码以便控制台应用程序不会退出,因此控制台应用程序会等待服务返回的值?

我们需要告诉Main等待Test完成。我们还需要Test来返回Task而不是void,因为我们可以等待Task,但我们无法等待void

这可能接近您需要的结构:

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main(string[] args)
    {
        // use GetAwaiter().GetResult() to prevent
        // the program from exiting until after
        // the async task(s) have completed.
        Test().GetAwaiter().GetResult();
    }

    static async Task Test()
    {
        await SyncADToDBAsync();
    }

    static async Task SyncADToDBAsync()
    {
        // for the sake of this example,
        // we are using Task.Delay(ms) to
        // emulate the non-blocking call to the HttpClient
        await Task.Delay(1000);
        Console.WriteLine("Do something with the response.");
    }
}

这是as a Fiddle。以下是a GitHub issue,指的是使用GetAwaiter().GetResult()