Come faccio ad aggiornare la mia interfaccia utente da HttpWebRequest.BeginGetRequestStream in Silverlight

StackOverflow https://stackoverflow.com/questions/13217

  •  08-06-2019
  •  | 
  •  

Domanda

Sto caricando più file utilizzando BeginGetRequestStream di HttpWebRequest ma desidero aggiornare il controllo di avanzamento che ho scritto mentre pubblico il flusso di dati.

Come dovrebbe essere fatto, ho provato a chiamare Dispatch.BeginInvoke (come sotto) dall'interno del ciclo che inserisce i dati nel flusso ma blocca il browser fino al termine, quindi sembra essere in una sorta di deadlock del thread lavoratore/interfaccia utente .

Questo è uno snippet di codice praticamente di quello che sto facendo:

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;
        } );
    }
}
È stato utile?

Soluzione

Stavo per dirlo, non pensavo che HttpWebRequest di Silverlight 2 supportasse lo streaming, perché i dati della richiesta vengono interamente memorizzati nel buffer.Era passato un po' di tempo dall'ultima volta che l'ho guardato, quindi sono tornato per vedere se la Beta 2 lo supportava.Beh, a quanto pare è così.Sono felice di essere tornato a leggere prima di affermarlo.Puoi abilitarlo impostando EnableReadStreamBuffering su false.Hai impostato questa proprietà sul tuo HttpWebRequest?Ciò potrebbe causare il tuo blocco.

Modifica, ho trovato un altro riferimento per te.Potresti voler seguire questo approccio suddividendo il file in blocchi.Questo è stato scritto lo scorso marzo, quindi non sono sicuro se funzionerà nella Beta 2 oppure no.

Altri suggerimenti

Grazie per questo, darò un'occhiata a quei collegamenti, stavo comunque valutando la possibilità di suddividere i miei dati in blocchi, sembra essere l'unico modo per ottenere rapporti ragionevoli sui progressi da essi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top