2010-12-01 11 views
2

私はHttpWebRequest POSTメソッドの結果をReactiveインターフェイスIObservable経由で返す単一のメソッドを試みています。HttpWebRequest POSTメソッドの結果をIObservableインターフェイス経由で返すことは可能ですか

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); 

をしかし、私はどのように一緒にチェーンが必要です応答ストリームの読み取りを要求ストリームに書き込むの非同期オブザーバーをするわからない午前:私は以下のコードを使用して、GETメソッドのためにこれを行うことができました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); 

答えて

-1

obs1.Concat(obs2)おそらく?

+0

彼らは同じタイプではないので、私は連結できません。どうもありがとうございます – AwkwardCoder

+0

申し訳ありませんが、私は当時注目されていませんでした。私は今からヒップから火を使わないようにしようと思うでしょう:) – rawpower

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 
    }); 

要求ストリームにあなたの文章が非同期であれば、私に教えてください、私はそれに応じてサンプルを更新することができます。私は、あなたが探していることはこれだと思います。

+0

私は似たようなことをしましたが、観測者に複数のサブスクライバがある場合、 'SelectMany'は複数回起動し、これは要求された動作ではありません。理想的にはリクエストストリームへの書き込みは一度だけです... – AwkwardCoder

+0

@AWC - 最後の値を記憶するために 'Prune'または' Replay'を使いたいと思うように聞こえます。 –

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で非同期ポストに使用するストリームを提供し、3番目のストリームはアップロードの結果を無視します(したがって、変わった名前の変数 '_')。応答を得る。

この例では、Observableという概念を拡張しています。私はあなたがTaskを使ってより良い結果とより読みやすいコードを得られると思うし、おそらくC#5で新しい非同期サポートを使ったほうが良い結果になっていると思う。

+0

これはSilverlightでも使用されていますが、ブロッキングメソッドはなく、HttpWebRequestクラスの使用をカプセル化し、クライアントが簡単に購読できるインターフェイスを介してすべての結果を「プッシュ」するクラスを作成しようとしていました。更新のおかげで、私は朝に前にそれを与えるでしょう... – AwkwardCoder

+0

しかし、このコードはあなたのテストに合格しません - 私はちょうど以下の応答とあなたのコメントを見ました - あなたがこれを2回購読すれば、以前の呼び出しがまだ進行中のときにBeginGetRequestStreamを再度呼び出すことを訴えて例外が発生し、サブスクライバが失敗します。私が言ったように、これはタスクベースのアプローチではるかに良く解決できる可能性があります。少なくとも私の頭の中ではそれは意味があります。しかし、面白い挑戦に感謝します。 – rawpower

+0

もう1つ - 私はプレーン.NET 4を使用しました。0のコンソールアプリケーションではなく、Silverlightではなく、自分で解決できない大きな違いはありません。 – rawpower

関連する問題