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
可以减少您那里的代码。
我正在尝试将数据上传到外部网络服务,我正在使用 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
可以减少您那里的代码。