Silverlight HttpWebRequest同步调用 [英] Silverlight HttpWebRequest syncronous call

查看:108
本文介绍了Silverlight HttpWebRequest同步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my silverlight app I do a file upload. I break the file into chunks and then I upload each chunk. The problem is that I want to use the HttpWebRequest synchronously. My propblem is to ensure that all request are ok and to catch exceptions. Is that possible in Silverlight? I would like sopmething like:

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)
    {...}
}

您能给我一个提示,我如何获得它?

Can you give me a hint how can I obtain this?

谢谢, Radu D

Thanks, Radu D

推荐答案

Silverlight不支持同步Web请求.因此,我写了简单的异步操作运行器.目标之一是能够像同步代码一样编写代码,然后对其进行修改以使其与运行程序代码一起工作.

Silverlight does not support synchronous web requests. For this reason I wrote the Simple Asynchronous Operation Runner. One of the objectives is to be able to write code as if it were synchronous then modify it to work with the runner code.

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

First get the small chunk of code for the AsyncOperationService from part 1 and add it to your project (don't worry if you find the article a little heavy its not important to actually using it).

使用已经作为同步模板"提供的代码,我们可以看到我们需要为GetRequestStreamGetResponseStream使用几个AsyncOperation实现,因此我们也将它们添加到项目中:

Using the code you already provided as "synchronous template" we can see we need a couple of AsyncOperation implementations for GetRequestStream and GetResponseStream so we'll write those an add them to the project as well:-

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类中):-

Now if you are chunking a file upload you'll probably want to report progress into the UI so I would suggest you have this AsyncOperation on hand as well (inject in to the existing AsyncOperationService class):-

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

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

Now we can creare an asynchronous version of your code:-

 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;
          }
      }
 }

最后,您只需要运行它并处理所有错误:-

Finally you just need to run it and handle any error:-

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

 });

这篇关于Silverlight HttpWebRequest同步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆