与BeginGetRequestStream / EndGetRequestStream的TaskFactory.FromAsync挂起

我有一个像这样的方法,在使用Task.Factory.FromAsync()声明responseObject时挂起

 private async Task post(string url, string postdata) { var request = WebRequest.Create(new Uri(url)) as HttpWebRequest; request.Method = "POST"; // this works Task requestStream = Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, request); var sw = new StreamWriter(requestStream.Result); byte[] data = Encoding.UTF8.GetBytes(postdata); await requestStream.Result.WriteAsync(data, 0, data.Length); // this hangs Task responseObject = Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, request); // Hangs here // Doesn't get to here var responseStream = responseObject.Result.GetResponseStream(); var sr = new StreamReader(responseStream); string received = await sr.ReadToEndAsync(); return received; } 

如果我手动运行Begin / End方法,它可以正常工作,如下所示:

  request.BeginGetRequestStream(async ar => { var requestStream = request.EndGetRequestStream(ar); using (var sw = new StreamWriter(requestStream)) { byte[] data = Encoding.UTF8.GetBytes(postdata); await requestStream.WriteAsync(data, 0, data.Length); } request.BeginGetResponse(async a => { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(a); var responseStream = response.GetResponseStream(); using (var sr = new StreamReader(responseStream)) { string received = await sr.ReadToEndAsync(); } }, null); }, null); 

但是,在这种情况下,ReadToEndAsync()在一个单独的线程上运行,我希望该方法返回结果,这是因为该方法在BeginGetResponse回调完成之前返回,这是不可能的。

在这一点上,我认为我正在做这个可怕的错误,并且这完全是错误的方式,所以任何帮助将非常感激。

首先:不要在异步方法中使用“.Result”。 这将阻止运行方法的线程。 改为使用“await”,因此线程会在获取结果时跳回到您的方法。

您的代码的问题是您打开请求流,但您永远不会关闭它。 那么什么时候应该完成你的请求并发送它? 它总是期望有更多的输入,直到请求在超时运行。 您还没有设置内容类型和内容长度。

 private async Task post(string url, string postdata) { var request = WebRequest.Create(new Uri(url)) as HttpWebRequest; request.Method = "POST"; byte[] data = Encoding.UTF8.GetBytes(postdata); request.ContentLength = data.Length; using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, request)) { await requestStream.WriteAsync(data, 0, data.Length); } WebResponse responseObject = await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, request); var responseStream = responseObject.GetResponseStream(); var sr = new StreamReader(responseStream); string received = await sr.ReadToEndAsync(); return received; }