¿Cuál es la mejor manera de cancelar un DownloadFileAsync operación de forma segura?

Tengo un hilo (trabajo en segundo plano) que se inicia la descarga y administra otros aspectos de la misma y que termino cuando veo que el hilo ha CancellationPending == true. Después de pistoletazo de salida para la descarga, el hilo va a sentarse y girar hasta que la descarga se haya completado, o el hilo se cancela.

Si el hilo está cancelado, quiero cancelar la descarga. ¿Hay un modelo de lenguaje para hacer esto? He intentado CancelAsync, pero me da un WebException de ella (abortados). No estoy seguro de que esta es una buena manera de hacer que la cancelación.

Gracias.

Edit: la primera excepción es y objeto dispuestos uno en la secuencia interna (pila de llamadas):

System.dll!Sistema.Net.Sockets.NetworkStream.EndRead(Del Sistema.IAsyncResult asyncResult)
Sistema.dll!Sistema.Net.PooledStream.EndRead(Del Sistema.IAsyncResult asyncResult)

InformationsquelleAutor Robinson | 2012-04-26

1 Comentario

  1. 6

    No estoy seguro de por qué usted podría obtener una excepción de llamar a CancelAsync.

    Yo uso WebClient para manejar paralelo descargas en nuestro proyecto actual, y tras llamar a CancelAsync el evento DownloadFileCompleted es planteado por WebClient, donde la propiedad Cancelled es cierto. Mi controlador de eventos se parece a esto:

    private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            this.CleanUp(); //Method that disposes the client and unhooks events
            return;
        }
    
        if (e.Error != null) //We have an error! Retry a few times, then abort.
        {
            if (this.retryCount < RetryMaxCount)
            {
                this.retryCount++;
                this.CleanUp();
                this.Start();
            }
    
            //The re-tries have failed, abort download.
            this.CleanUp();
            this.errorMessage = "Downloading " + this.fileName + " failed.";
            this.RaisePropertyChanged("ErrorMessage");
            return;
         }
    
         this.message = "Downloading " + this.fileName + " complete!";
         this.RaisePropertyChanged("Message");
    
         this.progress = 0;
    
         this.CleanUp();
         this.RaisePropertyChanged("DownloadCompleted");
    }

    Y la cancelación método es simplemente:

    ///<summary>
    ///If downloading, cancels a download in progress.
    ///</summary>
    public virtual void Cancel()
    {
        if (this.client != null)
        {
            this.client.CancelAsync();
        }
    }
    • Gracias por este. He actualizado la pregunta para mostrar lo que yo estoy haciendo (ahora mismo, estoy en primer lugar llegar a un objeto de desechar la excepción de que parece ser que viene de la secuencia subyacente). Tal vez sea yo la Cancelación por no esperar alrededor de finalización? Voy a investigar.
    • Tal vez esto podría ser de interés a continuación: «El Objeto de Desechar la excepción es lanzada, atrapado e ignorada por el WebClient si se descarga el archivo, lo suficientemente rápido que el progreso de los eventos de cambio están siendo tramitadas después de que el archivo se ha cerrado.» (referencia: stackoverflow.com/questions/3169749/…)
    • También debe tener en cuenta que CancelAsync no cancelar la descarga inmediatamente, de modo que si, por ejemplo, disponer de los objetos demasiado pronto podrían estar recibiendo un Objeto de Desechar la excepción porque el proceso no ha sido cancelado todavía.
    • Estoy buscando en él…
    • Ok Amadeus, puedo ver que usted está llamando a CancelAsync y que está a la espera de la DownloadFileCompleted evento. Que es lo que estoy haciendo demasiado. Mina establece un indicador en que el método que rompe un giro de bloqueo en otro hilo. Sólo entonces el WebClient obtener eliminados. Así que soy una especie de todavía frotando mi cabeza un poco. Esto sucede cuando estoy cerca de un formulario por el camino, llamado de la FormClosing método. Llama a Disponer en el alojamiento de objeto WebClient, y deben esperar hasta que se haya recibido la DownloadComplete evento antes de la disposición.
    • Ok, creo que estoy haciendo lo correcto, pero el objeto subyacente es lanzar y atrapar/manejo de excepciones que VS es la presentación de informes a mí. Me gustaría poder cambiar simplemente de una instancia de objeto :). De todos modos como me las arreglé para verificar mi patrón contra la tuya y todo es bueno… tiene algunos puntos.

Dejar respuesta

Please enter your comment!
Please enter your name here