我需要在Silverlight库中实现一个方法,该方法通过httpwebrequest调用(非wcf-)服务,获取响应,然后填充一个对象并返回它。
因为这是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);
}
我想我可以在读取读取后立即填充对象.ReadToEnd(),但我在哪里实际返回它?我无法在回调函数中返回它,但是如果我在GetMyObject()的末尾返回它,则不能保证自asynch回调以来填充对象。
提前致谢!
答案 0 :(得分: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
});
});