控制台应用程序中的 PostAsync 从不 returns

PostAsync never returns in console application

我正在尝试实现一个简单的 XML HTTP POST 接口,但不知何故它停止工作了。这是我的代码:

    HttpClient _httpClient = new HttpClient();

    static void Main(string[] args)
    {
        Login("", "");
    }

    public async void Login(string username, string password)
    {
        var response = await SendXml("<foo>");
    }

    public async Task<string> SendXml(string xml)
    {
        var content = new StringContent(xml);
        var response = await _httpClient.PostAsync("http://127.0.0.1:8080/Path", content);
        var responseBody = await response.Content.ReadAsStringAsync();

        return responseBody;
    }

我会说很简单,但是当 运行 时,它就停在 PostAsync。当我在 ReadAsStringAsync 处放置断点时,它永远不会命中。

我没有异常,没有错误。我的服务器显示“发送数据时连接中止”。

我一定是犯了一些简单的错误,但我找不到...我必须说 await 的东西仍然让我有点困惑。此代码是一个控制台应用程序,async/await 会导致此处出现问题吗?

当您使用基于任务的操作时,您需要使应用程序一直异步到应用程序的入口点,通常是 Program.Main()

如果您使用的是 C# >= 7.1,则可以使用 MainAsync

namespace MyApp
{
    public class Program
    {
        private readonly static HttpClient _httpClient = new HttpClient();
        
        public async static Task Main()
        {
            var response = await SendXml("myxml");
        }

        public async static Task<string> SendXml(string xml)
        {
            var content = new StringContent(xml);
            var response = await _httpClient.PostAsync("http://127.0.0.1:8080/Path", content);
            var responseBody = await response.Content.ReadAsStringAsync();

            return responseBody;
        }
    }
}

如果您使用的是旧版本,则不支持异步入口点,但您可以这样写:

namespace MyApp
{
    public class Program
    {
        private readonly static HttpClient _httpClient = new HttpClient();
        
        public static void Main()
        {
            try
            {
                MainAsync().GetAwaiter().GetResult();
            }
            catch (System.Exception)
            {
                // TODO: log unhandled exception
                throw;
            }
        }

        private static Task MainAsync()
        {
            var response = await SendXml("myxml");
        }

        public async static Task<string> SendXml(string xml)
        {
            var content = new StringContent(xml);
            var response = await _httpClient.PostAsync("http://127.0.0.1:8080/Path", content);
            var responseBody = await response.Content.ReadAsStringAsync();

            return responseBody;
        }
    }
}

在最后一种情况下,请确保只有一个点可以调用 GetAwaiter().GetResult() 而不是其他任何地方,因为这可能会导致死锁。