2011-09-16 5 views
1

は私にWebResponseを閉じるFromAsyncPatternます:FromAsyncPatternは使用されなくなったリソースを破棄しますか?

var o = Observable.Return(HttpWebRequest.Create("http://foo.com")) 
        .SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
         r.BeginGetResponse, 
         r.EndGetResponse)()) 
        .Select(r => r.ContentLength); 
// The response is now disposed 

または私はそれを手動で行う必要がありますか?

var o = Observable.Return(HttpWebRequest.Create("http://foo.com")) 
        .SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
         r.BeginGetResponse, 
         r.EndGetResponse)()) 
        .Select(r => Tuple.Create(r, r.ContentLength)) 
        .Do(t => t.Item1.Close()) 
        .Select(t => t.Item2); 

手動で行う必要がある場合は、これよりも良い方法がありますか?

答えて

1

として少しUsingクエリのクリーナーバージョンはこのようになります:

var o = 
    from rq in Observable.Return(HttpWebRequest.Create("http://foo.com")) 
    from cl in Observable.Using(() => rq.GetResponse(), 
     rp => Observable.Return(rp.ContentLength)) 
    select cl; 

私は、少なくとも第1 ReturnScheduler.ThreadPoolを追加することを示唆していますオブザーバブルをバックグラウンドスレッドで実行させる - デフォルトはScheduler.Immediateです。

1

FromAsyncPatternは、希望していたとしても、あなたのリソースを閉鎖できるとは思いません。非同期呼び出しを行うオブジェクト(この場合はHttpWebRequest)または非同期呼び出し(この場合はWebResponse)から返されたオブジェクトのいずれかが、どこに保存されているかを知るために使用される方法に関する十分な情報がありませんDispose

つまり、特別なDoSelectコールを使わずにリソースを手動で閉じることができます。

.Select(r => { using (r) { return r.ContentLength; }}); 

私がのがObservable.Using知っているDisposeを呼び出すだけのRxオペレータ:ちょうどに最初の例ではSelectを変更します。しかし、その署名に基づいて、ここでどのように適用できるかどうかはすぐには分かりませんでしたので、私は上記の方法を採用しました。

4

Observable.Usingは、この目的のために使用することができます。

var o = Observable.Return(HttpWebRequest.Create("http://www.google.com")) 
        .SelectMany(r => Observable.FromAsyncPattern<WebResponse>(
         r.BeginGetResponse, 
         r.EndGetResponse)()) 
        .SelectMany(r => 
        { 
         return Observable.Using(() => r, (resp) => Observable.Return(resp.ContentLength)); 
        }); 
関連する問題