tags:

views:

2155

answers:

2

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;
     } );
    }
}
+1  A: 

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.

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.

Dale Ragan
A: 

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.

Cheers.

Dan