2011-08-31 22 views
1

我需要在Silverlight庫中實現一個方法,該方法通過httpwebrequest調用(非wcf-)服務,獲取響應,然後填充對象並將其返回。從Silverlight中的服務調用返回對象

因爲這是Silverlight,所以響應異步返回,所以我無法找出這個對象應該在哪裏填充以及應該如何返回。

這是我到目前爲止的代碼:

public MyObject GetMyObject 
    { 
     HttpWebRequest req = WebRequest.Create(MyUri) as HttpWebRequest; 
     req.Method = "GET"; 
     req.Accept = "application/json"; 

     req.BeginGetResponse((cb) => 
     { 
      HttpWebRequest rq = cb.AsyncState as HttpWebRequest; 
      HttpWebResponse resp = rq.EndGetResponse(cb) as HttpWebResponse; 
      string result; 
      using (StreamReader reader = new StreamReader(resp.GetResponseStream())) 
      { 
       result = reader.ReadToEnd(); 
       reader.Close(); 
      }     
     }, req); 

    } 

我想我可以填充之後我做reader.ReadToEnd(),但我在哪裏實際上將返回的對象呢?我不能在回調函數中返回它,但是如果我在GetMyObject()的末尾返回它,那麼由於異步回調,對象不能保證被填充。

在此先感謝!

回答

0

首先,您需要認識到,當一系列操作(我們通常稱爲「代碼」)包含異步完成的操作時,整個序列事實上是異步的。

在同步世界中,我們有返回指定類型的函數。在異步世界中,這些函數返回void,而代之以傳遞給它們的委託(我們稱之爲回調函數),其中委託接受指定類型的參數。由於你的函數內部步入異步世界,所以它也必須(因爲它已經成爲一個現在是異步的序列的一部分)。所以它的簽名需要改變。現在應該是這樣的: -

public void GetMyObject(Action<MyObject> returnResult) 
    { 
     HttpWebRequest req = WebRequest.Create(MyUri) as HttpWebRequest; 
     req.Method = "GET"; 
     req.Accept = "application/json"; 

     req.BeginGetResponse((cb) => 
     { 
      WebResponse resp = req.EndGetResponse(cb); 
      string json; 
      using (StreamReader reader = new StreamReader(resp.GetResponseStream())) 
      { 
       json = reader.ReadToEnd(); 
       reader.Close(); 
      } 
      MyObject result = SomethingDoDeserialiseJSONToMyObject(json); 
      returnResult(result); 
     }, null); 

    } 

你會再調用使用此方法如下方法: -

GetMyObject(result => 
    { 
     Dispatcher.BeginInvoke(() => 
     { 
      // Display result in UI 
     }); 
    }); 
+0

感謝這麼多的詳細解釋和例子。真的很感激它! – TeeZee