Silverlight HttpWebRequest Synchronous Call

In my silverlight application, I upload a file. I break the file into pieces and then upload each piece. The problem is that I want to use HttpWebRequest synchronously. My recommendation is to make sure all requests are approved and catch exceptions. Is this possible in Silverlight? I would like to forgive:

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 get this?

Thank you Radu D

+4
source share
2 answers

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

First, get a small piece of code for AsyncOperationService from the first part and add it to your project (don’t worry if you find that the article is a little heavy, which is not important for its actual use).

Using the code that you have already indicated as a “synchronous template”, we see that we need a couple of AsyncOperation implementations for GetRequestStream and GetResponseStream , so we will write them by adding them to the project:

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

Now, if you are uploading a file, you will probably want to report the progress in the user interface, so I suggest you have this AsyncOperation on hand (type in the existing AsyncOperationService class): -

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

Now we can create 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. } }); 
+2
source

It is absolutely not recommended to block the main user interface thread by performing a synchronous function.

You can still load your large file into chunks using the async mechanism. If you are using the WCF service, check out this post . I did the same using the Soap web service running on JAXWS, so it has nothing to do with your choice.

+1
source

Source: https://habr.com/ru/post/1346548/


All Articles