Trabajador en segundo plano: informar el progreso con una matriz de cadenas
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.
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.
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);
}
}