Возврат объекта из сервисного вызова в Silverlight - PullRequest
1 голос
/ 01 сентября 2011

Мне нужно реализовать метод в библиотеке Silverlight, который вызывает (не-wcf-) сервис через httpwebrequest, получает ответ, затем заполняет объект и возвращает его.

Поскольку это 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 (), не гарантируется заполнение объекта после асинхронного обратного вызова.

Заранее спасибо!

1 Ответ

0 голосов
/ 01 сентября 2011

Прежде всего вам нужно признать, что когда последовательность операций (которую мы обычно называем «кодом») включает в себя операцию, которая завершается асинхронно, тогда вся последовательность фактически асинхронна.

В синхронном мире у нас есть функции, которые возвращают указанный тип.В асинхронном мире эти функции возвращают 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
       });
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...