UploadDataTaskAsync 从不 returns

UploadDataTaskAsync never returns

我正在尝试将数据上传到外部网络服务,我正在使用 WebClients UploadDataTaskAsync 异步执行此操作。但它从来没有 returns。我已经使用同步调用对此进行了测试,它最终会超时。

public Notification Notify(Notification notification)
{
    var messageXml = MessageFactory.Create(notification);
    var statusCode = SendWebRequestAsync(messageXml);

    notification.ProcessedAttempts++;
    if (statusCode.Result == HttpStatusCode.OK)
    {
        notification.Processed = true;
        notification.DateProcessed = DateTime.UtcNow;
    }
    return notification;
}

private async Task<HttpStatusCode> SendWebRequestAsync(string message)
{
    using (var webClient = new WebClient())
    {
        byte[] data = message.ToUtf8Bytes();

        var uri = new Uri(url);
        try
        {
            webClient.UploadDataCompleted += WebClient_UploadDataCompleted;
            var result = await webClient.UploadDataTaskAsync(uri, "POST", data);
            string response = Encoding.UTF8.GetString(result);

            if (response == "")
                return HttpStatusCode.OK;
            return HttpStatusCode.NoContent;
        }
        catch (WebException ex)
        {
            if (ex.Status == WebExceptionStatus.ProtocolError)
            {
                var response = ex.Response as HttpWebResponse;
                if (response != null)
                {
                    return response.StatusCode;
                }
            }
            // no http status code available
            return HttpStatusCode.ServiceUnavailable; // guess
        }
        catch (Exception)
        {
            return HttpStatusCode.InternalServerError;
        }
    }
}

private void WebClient_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
{
    Console.WriteLine(e.Result);
} 

您正在调用 statusCode.Result,这是典型的 ASP.NET 死锁。这没有任何意义,因为您显然是在使用异步 IO 来获得可扩展性优势,然后通过阻塞破坏它。

不要阻止。

此外,看起来 HttpClient 可以减少您那里的代码。