C# 如何从 Silverlight 中的 HttpWebRequest.BeginGetRequestStream 更新我的 UI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I update my UI from within HttpWebRequest.BeginGetRequestStream in Silverlight
提问by Dan
I am uploading multiple files using the BeginGetRequestStream of HttpWebRequest but I want to update the progress control I have written whilst I post up the data stream.
我正在使用 HttpWebRequest 的 BeginGetRequestStream 上传多个文件,但我想更新我在发布数据流时编写的进度控制。
How should this be done, I have tried calling Dispatch.BeginInvoke (as below) from within the loop that pushes the data into the stream but it locks the browser until its finished so it seems to be in some sort of worker/ui thread deadlock.
这应该怎么做,我尝试从循环内调用 Dispatch.BeginInvoke(如下所示),将数据推送到流中,但它会锁定浏览器直到完成,因此它似乎处于某种工作/用户界面线程死锁.
This is a code snippet of pretty much what I am doing:
这是我正在做的事情的代码片段:
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;
} );
}
}
采纳答案by Dale Ragan
I was going to say that, I didn't think that Silverlight 2's HttpWebRequest supported streaming, because the request data gets buffered into memory entirely. It had been a while since the last time I looked at it though, therefore I went back to see if Beta 2 supported it. Well turns out it does. I am glad I went back and read before stating that. You can enable it by setting AllowReadStreamBuffering to false. Did you set this property on your HttpWebRequest? That could be causing your block.
我想说的是,我不认为 Silverlight 2 的 HttpWebRequest 支持流式传输,因为请求数据完全缓存到内存中。自从我上次看它已经有一段时间了,因此我回去看看 Beta 2 是否支持它。事实证明确实如此。我很高兴我在陈述之前回去阅读了。您可以通过将 AllowReadStreamBuffering 设置为 false 来启用它。您是否在 HttpWebRequest 上设置了此属性?这可能会导致您的阻塞。
Edit, found another reference for you. You may want to follow this approach by breaking the file into chunks. This was written last March, therefore I am not sure if it will work in Beta 2 or not.
编辑,为您找到了另一个参考。您可能希望通过将文件分成块来遵循此方法。这是去年三月写的,因此我不确定它是否适用于 Beta 2。
回答by Dan
Thanks for that, I will take a look at those links, I was considering chunking my data anyway, seems to be the only way I can get any reasonable progress reports out of it.
谢谢你,我会看看这些链接,无论如何我都在考虑对我的数据进行分块,这似乎是我从中获得任何合理进度报告的唯一方法。