2

我試圖創建一個基於Rx的WebRequestFactory來使用任何通用API。在Windows Phone 7上創建WebRequestFactory

我已經有了一個基本的GET請求半分類

public static IObservable<T> GetData<T>(Uri uri, Func<string, T> generator) 
{ 
    System.Diagnostics.Debug.WriteLine(uri); 
    return (from request in Observable.Return(CreateWebRequest(uri)) 
      from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)() 
      select generator(new StreamReader(response.GetResponseStream()).ReadToEnd())).ObserveOnDispatcher(); 
} 

private static WebRequest CreateWebRequest(Uri uri) 
{ 
    var ret = (HttpWebRequest)WebRequest.Create(uri); 
    ret.AllowReadStreamBuffering = false; 
    return ret; 
} 

效果很好,但我不能確定異常處理是如何完成的Rx,它是隻在訂閱()方法呢?即訂閱(onNext:response => handleResponse(response),onError:error => handleError(error)或者我可以早一點看到它?

我也很難獲取GetData的POST版本,

public static IObservable<T> PostData<T>(Uri uri, Func<string, T> generator, String postData) 
{ 
    System.Diagnostics.Debug.WriteLine(uri); 
    byte[] buffer = Encoding.UTF8.GetBytes(postData); 

    var request = CreatePOSTWebRequest(uri); 

    var obs1 = Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)(); 

    return null; 
} 

private static WebRequest CreatePOSTWebRequest(Uri uri) 
{ 
    var ret = (HttpWebRequest)WebRequest.Create(uri); 
    ret.Method = "POST"; 
    ret.AllowReadStreamBuffering = false; 
    return ret; 
} 

但我不知道如何連接POST數據事件的發送,然後服務器響應的檢索。

它使用異步HTTPRequests的我的第一次,所以任何幫助,將不勝感激

編輯:(我希望這個我S中的堆棧溢出推薦的方法添加到我的問題)

我覺得我已經通過使用Web客戶端,而不是解決它:

public static IObservable<T> PostData<T>(Uri uri, Func<string, T> generator, String postData) 
{ 
    System.Diagnostics.Debug.WriteLine(uri); 
    WebClient wc = CreatePostWebClient(uri, postData); 
    return (from e in Observable.FromEvent<UploadStringCompletedEventArgs>(wc, "UploadStringCompleted") 
      select generator(e.EventArgs.Result)).ObserveOnDispatcher(); 

} 

public static WebClient CreatePostWebClient(Uri uri, string postData) 
{ 
    var wc = new WebClient(); 
    wc.AllowReadStreamBuffering = false; 
    wc.UploadStringAsync(uri, postData); 
    return wc; 
} 

但我關心的是競爭條件盛傳它給我一點點,正如我在觀察響應之前開始上傳。

回答

2

你是對的,錯誤處理是通過向管道發送一個OnError消息並取消訂閱來源完成的。有些操作員可以改變這種行爲,如Catch,它可以提供一個新的序列來代替(例如,使用Observable.Return返回默認值)。除非你計劃實際上異步緩衝請求數據,以免阻塞客戶端(在這種情況下,它變得非常複雜),所以發佈數據不應該太困難。只要它只是發佈數據,它應該僅僅是這樣的:

return (from request in Observable.Return(CreateWebRequest(uri)) 
     from requestStream in Observable.FromAsyncPattern<WebResponse>(
            request.BeginGetRequest, request.EndGetRequest)() 
     from response in PostAndGetResponse(request, requestStream) 
     select generator(new StreamReader(response.GetResponseStream()).ReadToEnd()) 
     ).ObserveOnDispatcher(); 

private IObservable<WebResponse> PostAndGetResponse(
    WebRequest request, Stream requestStream) 
{ 
    // Write data to requestStream 

    return Observable.FromAsyncPattern<WebResponse>(
     request.BeginGetResponse, request.EndGetResponse)() 
} 
+0

感謝@Richard,給了我更多的思考,因爲最好我想做到這一切異步,也許使用Web客戶端? – Technicolour 2011-05-22 04:20:52