如何从 Silverlight 中的 HttpWebRequest.BeginGetRequestStream 更新我的 UI

Posted

技术标签:

【中文标题】如何从 Silverlight 中的 HttpWebRequest.BeginGetRequestStream 更新我的 UI【英文标题】:How do I update my UI from within HttpWebRequest.BeginGetRequestStream in Silverlight 【发布时间】:2010-09-06 00:10:15 【问题描述】:

我正在使用 HttpWebRequest 的 BeginGetRequestStream 上传多个文件,但我想更新我在发布数据流时编写的进度控件。

这应该怎么做,我尝试从将数据推送到流中的循环中调用 Dispatch.BeginInvoke(如下所示),但它会锁定浏览器直到完成,所以它似乎在某种工作者/ ui 线程死锁。

这是我正在做的几乎所有事情的代码 sn-p:

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

【问题讨论】:

【参考方案1】:

我要说的是,我不认为 Silverlight 2 的 HttpWebRequest 支持流式传输,因为请求数据被完全缓冲到内存中。自从我上次查看它已经有一段时间了,因此我回去看看 Beta 2 是否支持它。事实证明确实如此。我很高兴在说明之前我回去阅读了。您可以通过将 AllowReadStreamBuffering 设置为 false 来启用它。您是否在 HttpWebRequest 上设置了此属性?这可能会导致您的阻塞。

MSDN Reference File upload component for Silverlight and ASP.NET

编辑,为您找到另一个参考。您可能希望通过将文件分成块来遵循这种方法。这是去年 3 月编写的,因此我不确定它是否适用于 Beta 2。

【讨论】:

【参考方案2】:

谢谢你,我会看看那些链接,无论如何我都在考虑分块我的数据,这似乎是我可以从中获得任何合理进度报告的唯一方法。

【讨论】:

以上是关于如何从 Silverlight 中的 HttpWebRequest.BeginGetRequestStream 更新我的 UI的主要内容,如果未能解决你的问题,请参考以下文章

从 Silverlight 访问 Rally SOAP 服务

如何从 Silverlight 应用程序中刷新浏览器页面?

Silverlight:如何访问 DataGrid RowDetailTemplate 中的控件

如何在 Silverlight 中的 TextBox 上方定位菜单栏?

我无法从Silverlight业务应用程序中的代码中获取查询结果

如何从 wpf silverlight 应用程序注销