5

我正在开发一个 Windows Phone 7.1 应用程序,并尝试实现逻辑删除。

由于法律原因,我无法保存我的视图模型。我只保存加密的会话 ID,它可用于从远程服务器加载视图模型数据。

在恢复时,我需要验证会话 ID,如果它已过期 - 我将用户带到我的应用程序的登录页面,如果它仍然可以,我从服务器重新加载视图模型数据。

问题是 HttpWebRequest 缺少阻塞 API。此外,在去墓碑后的 page.OnNavigatedTo 方法内部,这里描述的方法永远阻塞。

我通过展示我自己的启动画面解决了这个问题。

但是,我宁愿在系统提供的“Resuming...”初始屏幕可见时完成这些 RPC 调用,即在我从 page.OnNavigatedTo 方法返回之前。

任何想法如何在去墓碑后在 page.OnNavigatedTo 内同步完成 HTTP 请求?

4

2 回答 2

0

更新:另一种选择是使用Reactive Extensions

如果您使用的是 VS2010,则可以安装AsyncCTP,并且当您执行此操作时,会添加一个扩展方法,允许您等待响应。

static async Task<Stream> AsynchronousDownload(string url)
  {
    WebRequest request = WebRequest.Create(url);
    WebResponse response = await request.GetResponseAsync();
    return (response.GetResponseStream());
  }

然后:

更新:

protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            var myResponse = await AsynchronousDownload("http://stackoverflow.com");
        }

或者

如果您使用的是 VS2012,则可以安装Microsoft.Bcl.Async库并执行与使用 AsyncCTP 相同的操作,await即响应。

或者

您可以在 Caliburn Micro 中实现类似于Coroutines的东西。为此,您实现 IResult 接口。

 public interface IResult
{
    void Execute(ActionExecutionContext context);
    event EventHandler<ResultCompletionEventArgs> Completed;
}

一个可能的实现:

public class HttpWebRequestResult : IResult
    {
        public HttpWebRequest HttpWebRequest { get; set; }
        public string Result { get; set; }

        public HttpWebRequestResult(string url)
        {
            HttpWebRequest = (HttpWebRequest) HttpWebRequest.Create(url);

        }

        public void Execute (ActionExecutionContext context)
        {
            HttpWebRequest.BeginGetResponse (Callback, HttpWebRequest);
        }

        public void Callback (IAsyncResult asyncResult)
        {
            var httpWebRequest = (HttpWebRequest)asyncResult.AsyncState;
            var httpWebResponse = (HttpWebResponse) httpWebRequest.EndGetResponse(asyncResult);

            using (var reader = new StreamReader(httpWebResponse.GetResponseStream()))
                Result = reader.ReadToEnd();

            Completed (this, new ResultCompletionEventArgs ());
        }

        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
    }

然后调用它:

var httpWebRequestResult = new HttpWebRequestResult("http://www.google.com");
            yield return httpWebRequestResult;
            var result = httpWebRequestResult.Result;

可能是从 CM 中获取 Coroutines 实现并单独使用它的示例。

于 2012-11-08T06:36:27.257 回答
0

首先让我说微软确实试图推动你进行异步调用是有充分理由的,这就是我想强调它的原因。

现在,如果您真的想同步进行,我有一个我无法测试自己的想法。使用HttpWebRequest类时,有两个重要的函数,您可能也使用过:BeginGetResponseEndGetResponse

这两个功能密切合作。BeginGetResponse启动一个异步 webrequest,当请求完成EndGetResponse时,它会在完成时为您提供输出。这是 MS 试图让你这样做的方式。同步做这些事情的诀窍是beginGetResponse返回一个IAsyncResult。该IAsyncResult接口包含一个WaitHandler,可用于同步等待,直到请求完成。之后,您可以继续使用 endGetRequest 并继续您的业务。BeginGetRequestStreamEndGetRequestStream也是如此。

但正如我之前所说,我没有测试过这个解决方案,它纯粹是理论上的。让我知道它是否有效。

祝你好运!

于 2012-11-08T06:56:15.860 回答