Comment mettre à jour mon interface utilisateur à partir de HttpWebRequest.BeginGetRequestStream dans Silverlight

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

  •  08-06-2019
  •  | 
  •  

Question

Je télécharge plusieurs fichiers à l'aide de BeginGetRequestStream de HttpWebRequest mais je souhaite mettre à jour le contrôle de progression que j'ai écrit pendant que je publie le flux de données.

Comment cela doit-il être fait, j'ai essayé d'appeler Dispatch.BeginInvoke (comme ci-dessous) à partir de la boucle qui pousse les données dans le flux, mais il verrouille le navigateur jusqu'à ce qu'il soit terminé, il semble donc être dans une sorte d'impasse de thread de travail/interface utilisateur .

Ceci est un extrait de code d'à peu près ce que je fais :

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;
        } );
    }
}
Était-ce utile?

La solution

J'allais dire cela, je ne pensais pas que HttpWebRequest de Silverlight 2 prenait en charge le streaming, car les données de la requête sont entièrement mises en mémoire tampon.Cela faisait un moment depuis la dernière fois que je l'avais regardé, donc je suis revenu pour voir si la bêta 2 le prenait en charge.Il s'avère que c'est le cas.Je suis content d'être revenu et lu avant de dire cela.Vous pouvez l'activer en définissant AllowReadStreamBuffering sur false.Avez-vous défini cette propriété sur votre HttpWebRequest ?Cela pourrait être à l'origine de votre blocage.

Edit, j'ai trouvé une autre référence pour vous.Vous souhaiterez peut-être suivre cette approche en divisant le fichier en morceaux.Cela a été écrit en mars dernier, donc je ne sais pas si cela fonctionnera dans la bêta 2 ou non.

Autres conseils

Merci pour cela, je vais jeter un œil à ces liens, j'envisageais de toute façon de regrouper mes données, cela semble être le seul moyen d'en tirer des rapports d'avancement raisonnables.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top