Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I update my UI from within HttpWebRequest.BeginGetRequestStream in Silverlight

Tags:

c#

silverlight

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.

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.

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;
        } );
    }
}
like image 812
Dan Avatar asked Nov 14 '22 17:11

Dan


1 Answers

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.

  • MSDN Reference
  • File upload component for Silverlight and ASP.NET

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.

like image 56
Dale Ragan Avatar answered Dec 10 '22 13:12

Dale Ragan