C# Task.Factory.FromAsync相当于HttpWebRequest和请求流代码

C# Task.Factory.FromAsync相当于HttpWebRequest和请求流代码,c#,.net,asynchronous,task-parallel-library,task,C#,.net,Asynchronous,Task Parallel Library,Task,我有以下扩展方法用于对WebRequest对象使用异步调用 public static Task<WebResponse> GetReponseAsync(this WebRequest request) { return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); } public st

我有以下扩展方法用于对WebRequest对象使用异步调用

 public static Task<WebResponse> GetReponseAsync(this WebRequest request)
    {
        return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
    }

    public static Task<Stream> GetRequestStreamAsync(this WebRequest request)
    {
        return Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null);
    }
我使用另一段使用WebRequest的代码轻松地做到了这一点,但是不需要第一次调用GetRequestStream()

如何转换第一个代码块以使用扩展方法并使其等效


编辑我使用的是.NET 4.0,因此async/await当前不是一个选项。

您只需将
连续调用与
调用链接起来即可。根据经验,序列中每个异步操作将有一个ContinueWith。每个ContinueWith通常以
return
结束,下一个ContinueWith将开始处理其结果

request.GetRequestStreamAsync()
       .ContinueWith((trs) =>
           {
               var postData = System.Text.Encoding.ASCII.GetBytes("dummy");
               trs.Result.Write(postData, 0, postData.Length);
               return request.GetResponseAsync();
           }).Unwrap()
       .ContinueWith((resp) =>
           {
               using (var sr = new StreamReader(resp.Result.GetResponseStream()))
               {
                   var str = sr.ReadToEnd();
               }
           });
请注意,在我的代码(以及您的异步版本)中,并不是所有对象都像在原始版本中那样被处理


在每个步骤中,您可能希望检查状态或IsFaulted/IsCanceled属性,或者使用带有TaskContinuationOptions参数的ContinueWith重载。对于后一个选项,请注意前一个任务的完成方式与选项不匹配会导致任务取消。如果您需要传递错误,则该方法将不起作用。就我个人而言,我将所有检查打包到一个方法中,该方法要么通过错误和取消,要么在成功完成时运行委托。否则,您会很快得到大量样板检查代码。

您能使用
Microsoft.Bcl.Async
吗?我不确定,我以前从未使用过。如果可能的话,我更愿意与上面的第二个示例保持一致。将来,我将使用4.5实现async/await,但一步一个脚印。因为没有类似于
StreamReader.BeginReadToEnd
的东西,所以您的继续必须处理循环。这就是事情开始变得非常复杂的地方,
async
确实简化了事情。使用
ContinueWith
而不是
Microsoft.Bcl.Async
就像是在进入C之前强迫自己学习(并开发完整的解决方案)。换句话说,
ContinueWith
不是朝着
async
迈出的“一步”。试试
Microsoft.Bcl.async
。它使.NET4.0中的这种场景变得简单得多。无论如何,您都将迁移到4.5,那么为什么要修复已经解决的问题呢?
request.GetReponseAsync().ContinueWith(t =>
{
    if (t.Exception == null)
    {
        using (var sr = new StreamReader(t.Result.GetResponseStream()))
        {
            str = sr.ReadToEnd();
        }
    }
});
request.GetRequestStreamAsync()
       .ContinueWith((trs) =>
           {
               var postData = System.Text.Encoding.ASCII.GetBytes("dummy");
               trs.Result.Write(postData, 0, postData.Length);
               return request.GetResponseAsync();
           }).Unwrap()
       .ContinueWith((resp) =>
           {
               using (var sr = new StreamReader(resp.Result.GetResponseStream()))
               {
                   var str = sr.ReadToEnd();
               }
           });