Trabajador en segundo plano: informar el progreso con una matriz de cadenas

Resuelto andree asked hace 13 años • 3 respuestas

Necesito devolver múltiples valores STRING de mi trabajador en segundo plano en cada bucle, así que intenté usar el segundo parámetro ReportProgress como matriz de cadenas. Ejemplo de código:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    string[] workerResult = new string[2];
    for (int i=0; i<someNumber; i++)
    {
        //do some heavy calculating
        workerResult[0] = "this string";
        workerResult[1] = "some other string";
        backgroundWorker1.ReportProgress(i, workerResult) // also tried workerResult[] and [2]
    }
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    string[] results = (string[])e.UserState;

    MessageBox.Show(results[0]); // line of error
    MessageBox.Show(results[1]); // line of error
}

Se compila, pero en tiempo de ejecución, en el momento en que intento acceder a la cadena devuelta por Userstate, aparece un error: "La referencia de objeto no está configurada como una instancia de un objeto".

Para mí, parece que algo anda mal al pasar el parámetro de matriz al delegado ProgressChanged, o en el método ProgressChanged al intentar establecer valores de matriz de resultados.

andree avatar Mar 28 '11 19:03 andree
Aceptado

Su fragmento de código no puede reproducir el problema. Un error estándar es llamar a ReportProgress() y luego continuar modificando el objeto. El controlador de eventos tarda un poco en ejecutarse; verá el objeto modificado, no el original. Esto se evita simplemente creando un nuevo objeto para que el controlador de eventos siempre funcione con el original. Como esto:

        //do some heavy calculating
        for (int i = 0; i < 2; ++i) {
            string[] workerResult = new string[2];
            workerResult[0] = "this string";
            workerResult[1] = "some other string";
            backgroundWorker1.ReportProgress(i, workerResult);
        }

Observe cómo la declaración de creación de la matriz se mueve dentro del bucle.

Hans Passant avatar Mar 28 '2011 13:03 Hans Passant

Cuando instancias tu BackgroundWorker, tendrás que establecer reportprogress en verdadero:

worker = new BackgroundWorker { WorkerReportsProgress = true };

En el método de trabajo, solo necesitarás esto:

 worker.ReportProgress(10, "Message");

Luego algo como esto para captar el progreso:

private void WorkerProgressChanged(object sender, ProgressChangedEventArgs e) {
            if (e.UserState != null) {
                MessageBox.Show(e.UserState);
            }
        }
dcarneiro avatar Mar 28 '2011 12:03 dcarneiro