代码之家  ›  专栏  ›  技术社区  ›  Dan

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

  •  5
  • Dan  · 技术社区  · 16 年前

    如何做到这一点,我已经尝试从将数据推送到流中的循环中调用Dispatch.BeginInvoke(如下所示),但它会锁定浏览器直到完成,因此它似乎处于某种工作线程/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;
            } );
        }
    }
    
    2 回复  |  直到 16 年前
        1
  •  1
  •   Dale Ragan    16 年前

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

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

        2
  •  0
  •   burning_LEGION    12 年前

    谢谢你,我会看看那些链接,我一直在考虑把我的数据分块,这似乎是我从中得到合理进度报告的唯一途径。