Silverlight HttpWebRequest同步调用 [英] Silverlight HttpWebRequest syncronous call
问题描述
在我的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).
使用已经作为同步模板"提供的代码,我们可以看到我们需要为GetRequestStream
和GetResponseStream
使用几个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屋!