Como atualizo minha interface do usuário em HttpWebRequest.BeginGetRequestStream no Silverlight

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

  •  08-06-2019
  •  | 
  •  

Pergunta

Estou enviando vários arquivos usando BeginGetRequestStream de HttpWebRequest, mas quero atualizar o controle de progresso que escrevi enquanto publico o fluxo de dados.

Como isso deve ser feito, tentei chamar Dispatch.BeginInvoke (como abaixo) de dentro do loop que envia os dados para o fluxo, mas bloqueia o navegador até terminar, então parece estar em algum tipo de impasse de thread de trabalho/ui .

Este é um trecho de código basicamente do que estou fazendo:

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;
        } );
    }
}
Foi útil?

Solução

Eu ia dizer isso, não achei que o HttpWebRequest do Silverlight 2 suportasse streaming, porque os dados da solicitação são totalmente armazenados em buffer na memória.Já faz um tempo desde a última vez que olhei para ele, então voltei para ver se o Beta 2 suportava.Bem, acontece que sim.Estou feliz por ter voltado e lido antes de afirmar isso.Você pode habilitá-lo definindo AllowReadStreamBuffering como falso.Você definiu essa propriedade em seu HttpWebRequest?Isso pode estar causando o seu bloqueio.

Edite, encontrei outra referência para você.Você pode seguir esta abordagem dividindo o arquivo em partes.Isto foi escrito em março passado, portanto não tenho certeza se funcionará no Beta 2 ou não.

Outras dicas

Obrigado por isso, vou dar uma olhada nesses links, de qualquer maneira, estava pensando em agrupar meus dados, parece ser a única maneira de obter relatórios de progresso razoáveis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top