如何在Silverlight中从HttpWebRequest.BeginGetRequestStream中更新我的UI
时间:2020-03-05 18:40:04 来源:igfitidea点击:
我正在使用HttpWebRequest的BeginGetRequestStream上传多个文件,但我想更新在发布数据流时编写的进度控件。
我应该如何尝试从循环中调用Dispatch.BeginInvoke(如下所示),该循环将数据推入流中,但是它将浏览器锁定到完成,因此似乎处于某种worker / ui线程死锁中。
这是我正在做什么的代码片段:
class RequestState { public HttpWebRequest request; // holds the request public FileDialogFileInfo file; // store our file stream data public RequestState( HttpWebRequest request, FileDialogFileInfo file ) { this.request = request; this.file = file; } } private void UploadFile( FileDialogFileInfo file ) { UriBuilder ub = new UriBuilder( app.receiverURL ); ub.Query = string.Format( "filename={0}", file.Name ); // Open the selected file to read. HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri ); request.Method = "POST"; RequestState state = new RequestState( request, file ); request.BeginGetRequestStream( new AsyncCallback( OnUploadReadCallback ), state ); } private void OnUploadReadCallback( IAsyncResult asynchronousResult ) { RequestState state = (RequestState)asynchronousResult.AsyncState; HttpWebRequest request = (HttpWebRequest)state.request; Stream postStream = request.EndGetRequestStream( asynchronousResult ); PushData( state.file, postStream ); postStream.Close(); state.request.BeginGetResponse( new AsyncCallback( OnUploadResponseCallback ), state.request ); } private void PushData( FileDialogFileInfo file, Stream output ) { byte[] buffer = new byte[ 4096 ]; int bytesRead = 0; Stream input = file.OpenRead(); while( ( bytesRead = input.Read( buffer, 0, buffer.Length ) ) != 0 ) { output.Write( buffer, 0, bytesRead ); bytesReadTotal += bytesRead; App app = App.Current as App; int totalPercentage = Convert.ToInt32( ( bytesReadTotal / app.totalBytesToUpload ) * 100 ); // enabling the following locks up my UI and browser Dispatcher.BeginInvoke( () => { this.ProgressBarWithPercentage.Percentage = totalPercentage; } ); } }
解决方案
回答
我要说的是,我认为Silverlight 2的HttpWebRequest不支持流传输,因为请求数据已完全缓冲到内存中。自上次查看以来已经有一段时间了,因此我回过头来看看Beta 2是否支持它。好吧,事实确实如此。我很高兴自己回去阅读,然后再说。我们可以通过将AllowReadStreamBuffering设置为false来启用它。我们是否在HttpWebRequest上设置了此属性?那可能会导致封锁。
- MSDN参考
- Silverlight和ASP.NET的文件上传组件
编辑,为我们找到了另一个参考。我们可能希望通过将文件分成多个块来遵循这种方法。这是在去年三月编写的,因此我不确定它是否可以在Beta 2中使用。
回答
为此,我将看一下那些链接,无论如何我一直在考虑对数据进行分块,这似乎是从中获取任何合理进度报告的唯一方法。