我正在尝试使用单一方法通过Reactive接口IObservable返回HttpWebRequest POST方法的结果。我已经设法使用以下代码为GET方法执行此操作:
var request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(url);
request.Method = method;
request.Accept = GetHttpType();
request.CookieContainer = new CookieContainer();
return Observable.FromAsyncPattern(request.BeginGetResponse, ar => ProcessResponse(method, ar, request))()
.Select(r => r);
但我不确定如何通过读取HTTP POST操作所需的响应流来将写入请求流的异步观察者链接在一起。如何连接以下变量obs1
& obs2
一起,以便我可以返回obs2?
var request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(url);
var type = GetHttpType();
request.Method = method;
request.Accept = type;
request.ContentType = type;
request.CookieContainer = new CookieContainer();
var data = Serialize(requestResource);
var obs1 = Observable.FromAsyncPattern(request.BeginGetRequestStream, ar1 => ProcessRequest(method, data, ar1, request))
var obs2 = Observable.FromAsyncPattern(request.BeginGetResponse, ar2 => ProcessResponse(method, ar2, request))();
// How do I connect obs1 And obs2 together...
return obs2;
我原以为以下情况应该有效但是'ProcessResponse'方法永远不会被调用,有人知道为什么吗?
var obs1 = Observable.FromAsyncPattern(request.BeginGetRequestStream, ar1 => ProcessRequest(method, data, ar1, request))();
var obs2 = Observable.FromAsyncPattern(request.BeginGetResponse, ar2 => ProcessResponse(method, ar2, request));
return obs1.SelectMany(a => obs2(), (a, b) => b);
答案 0 :(得分:2)
FromAsyncPattern
期望BeginAction和EndAction方法都作为参数。我认为你在寻找的是:
HttpWebRequest httpRequest =
(HttpWebRequest)HttpWebRequest.Create("http://www.stackoverflow.com");
httpRequest.Method = "POST";
var requestAsync = Observable.FromAsyncPattern<Stream>(
httpRequest.BeginGetRequestStream, httpRequest.EndGetRequestStream);
var responseAsync = Observable.FromAsyncPattern<WebResponse>(
httpRequest.BeginGetResponse, httpRequest.EndGetResponse);
requestAsync()
.SelectMany(requestStream =>
{
// requestStream.Write
return responseAsync();
})
.Subscribe(webResponse =>
{
// complete
});
如果您对请求流的写入是异步的,我可以相应地更新示例。
答案 1 :(得分:1)
byte[] buffer1 = Encoding.UTF8.GetBytes(data); // assume post data is utf-8 encoded
var obs1 = Observable.FromAsyncPattern(request.BeginGetRequestStream, ar1 => request.EndGetRequestStream(ar1));
return from stream in obs1()
let obs2 = Observable.FromAsyncPattern((ac, state) => stream.BeginWrite(buffer1, 0, buffer1.Length, ac, state), ar2 => stream.EndWrite(ar2))
from _ in obs2()
let obs3 = Observable.FromAsyncPattern(request.BeginGetResponse, ar2 => request.EndGetResponse(ar2))
from response in obs3()
select response;
您使用SelectMany处于正确的轨道上,但我发现常规的LINQ语法更具可读性。我也通过异步发布改进了你的例子,即以异步方式写入上传流。基本上第一个from
给我们一个流,我们在第一个let中用于异步帖子,第三个将忽略上传的结果(因此奇怪地命名为变量'_'),最后是简单订阅的最后一个得到反应的结果。
我必须承认,我发现这个例子延伸了Observable
的概念。我认为使用Task
可以获得更好的结果和更易读的代码,甚至可能在C#5中使用新的异步支持更好的结果(但除了CPT之外不可用)。
答案 2 :(得分:-1)
obs1.Concat(obs2)
?