在我的 silverlight 应用程序中,我进行了文件上传。我将文件分成 block ,然后上传每个 block 。问题是我想同步使用 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)
{...}
}
你能给我一个提示,我怎样才能得到这个?
谢谢,
拉杜
最佳答案
Silverlight 不支持同步 Web 请求。出于这个原因,我写了Simple Asynchronous Operation Runner .目标之一是能够像编写同步代码一样编写代码,然后对其进行修改以与运行器代码一起使用。
首先获取 AsyncOperationService
的一小段代码从第 1 部分开始并将其添加到您的项目中(如果您发现文章有点沉重,请不要担心它对实际使用它并不重要)。
使用您已经作为“同步模板”提供的代码,我们可以看到我们需要几个 AsyncOperation
GetRequestStream
的实现和 GetResponseStream
所以我们将编写这些并将它们添加到项目中:-
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);
};
}
}
现在,如果您正在分 block 上传文件,您可能希望在 UI 中报告进度,所以我建议您使用
AsyncOperation
手头上(注入(inject)现有的 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.
}
});
关于Silverlight HttpWebRequest 同步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5537918/