【问题标题】:Silverlight HttpWebRequest syncronous callSilverlight HttpWebRequest 同步调用
【发布时间】:2011-04-04 20:28:53
【问题描述】:

在我的 silverlight 应用程序中,我进行了文件上传。我将文件分成块,然后上传每个块。问题是我想同步使用 HttpWebRequest 。我的问题是确保所有请求都正常并捕获异常。这在 Silverlight 中可能吗?我想要类似的东西:

while(chunk)
{
    try{
    HttpWebRequest req = ...
    req.BeginGetRequestStream(new AsyncCallback(WriteCallback), req);
    //add data into request stream
    req.BeginGetResponseStream(new AsyncCallback(ReadCallback), req);
    //parse the response
    chunk = new Chunk();
    }catch(Exception ex)
    {...}
}

你能告诉我如何获得这个吗?

谢谢, 拉度D

【问题讨论】:

    标签: silverlight synchronization httpwebrequest


    【解决方案1】:

    Silverlight 不支持同步 Web 请求。出于这个原因,我写了Simple Asynchronous Operation Runner。目标之一是能够像编写同步代码一样编写代码,然后对其进行修改以与运行器代码一起使用。

    首先从第 1 部分中获取 AsyncOperationService 的一小部分代码,并将其添加到您的项目中(如果您发现这篇文章有点沉重,对实际使用它并不重要,请不要担心)。

    使用您已经作为“同步模板”提供的代码,我们可以看到我们需要为 GetRequestStreamGetResponseStream 提供几个 AsyncOperation 实现,因此我们将编写这些代码并将它们添加到项目中:-

    public static class WebRequestAsyncOps
    {
        public static AsyncOperation GetRequestStreamOp(this WebRequest request, Action<Stream> returnResult)
        {
            return (completed) =>
            {
                request.BeginGetRequestStream((result) =>
                {
                    try
                    {
                        returnResult(request.EndGetRequestStream(result));
                        completed(null);
                    }
                    catch (Exception err)
                    {
                        completed(err);
                    }
                }, null);
            };
        }
    
        public static AsyncOperation GetResponseOp(this WebRequest request, Action<WebResponse> returnResult)
        {
            return (completed) =>
            {
                request.BeginGetResponse((result) =>
                {
                    try
                    {
                        returnResult(request.EndGetResponse(result));
                        completed(null);
                    }
                    catch (Exception err)
                    {
                        completed(err);
                    }
                }, null);
            };
        }
    }
    

    现在,如果您正在分块文件上传,您可能希望在 UI 中报告进度,所以我建议您也准备好这个AsyncOperation(注入现有的 AsyncOperationService 类):-

        public static AsyncOperation SwitchToUIThread()
        {
            return (completed => Deployment.Current.Dispatcher.BeginInvoke(() => completed(null)));
        }
    

    现在我们可以为您的代码创建一个异步版本:-

     IEnumerable<AsyncOperation> Chunker(Action<double> reportProgress)
     {
         double progress = 0.0;
         Chunk chunk = new Chunk();
         // Setup first chunk;
         while (chunk != null)
         {
              Stream outStream = null;
              HttpWebRequest req = ...
    
              yield return req.GetRequestStreamOp(s => outStream = s);
    
              // Do stuff to and then close outStream
              WebResponse response = null;
    
              yield return req.GetResponseOp(r => response = r);
    
              // Do stuff with response throw error is need be.
              // Increment progress value as necessary.
    
              yield return AsyncOperationService.SwitchToUIThread();
    
              reportProgress(progress);
    
              chunk = null;
              if (moreNeeded)
              {
                 chunk = new Chunk();
                 // Set up next chunk;
              }
          }
     }
    

    最后你只需要运行它并处理任何错误:-

     Chunker.Run((err) =>
     {
         if (err == null)
         {
              // We're done
         }
         else
         {
              // Oops something bad happened.
         }
    
     });
    

    【讨论】:

      【解决方案2】:

      绝对不能通过执行同步函数来阻塞主 UI 线程。

      您仍然可以使用异步机制分块上传大文件。如果您使用 WCF 服务,请查看 this post。我使用在 JAXWS 上运行的 Soap Web 服务做了同样的事情,所以它与您选择的后端无关。

      【讨论】:

        猜你喜欢
        • 2012-08-30
        • 2013-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        • 1970-01-01
        相关资源
        最近更新 更多