【问题标题】:TaskFactory.FromAsync with BeginGetRequestStream/EndGetRequestStream hangsTaskFactory.FromAsync 与 BeginGetRequestStream/EndGetRequestStream 挂起
【发布时间】:2012-12-31 06:25:55
【问题描述】:

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

private async Task<string> post(string url, string postdata)
        {
            var request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
            request.Method = "POST";

            // this works
            Task<Stream> requestStream = Task<Stream>.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<WebResponse> responseObject = Task<WebResponse>.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 回调完成之前返回。

在这一点上,我认为我这样做是非常错误的,并且完全以错误的方式进行,所以非常感谢任何帮助。

【问题讨论】:

    标签: c# asynchronous windows-phone-8


    【解决方案1】:

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

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

    private async Task<string> 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<Stream>.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, request))
            {
                await requestStream.WriteAsync(data, 0, data.Length);
            }
    
    
            WebResponse responseObject = await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, request);
            var responseStream = responseObject.GetResponseStream();
            var sr = new StreamReader(responseStream);
            string received = await sr.ReadToEndAsync();
    
            return received;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      • 2011-09-24
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多