c# - with - ¿Por qué recibo este error ?: "Operación cruzada de hilos no válida: Controle lbFolders accedido desde un hilo que no sea el hilo en el que se creó".
multithreading vb net (7)
Está intentando escribir en un control a partir de un hilo que no sea el hilo principal. Use Invoke o BeginInvoke.
void SetMax()
{
if (prgAll.InvokeRequired)
{
prgAll.BeginInvoke(new MethodInvoker(SetMax));
return;
}
prgAll.Maximum = lbFolders.SelectedItems.Count;
}
Esto me desconcierta, tal vez alguien pueda iluminar la luz de la educación con mi ignorancia. Esto está en una aplicación de Windows C #. Estoy accediendo a los contenidos de un listbox de un hilo. Cuando intento acceder de esta manera
prgAll.Maximum = lbFolders.SelectedItems.Count;
Me sale el error Sin embargo, esta es la parte que no entiendo. Si comento esa línea, la siguiente línea
foreach (string dir in lbFolders.SelectedItems)
ejecuta bien.
Editar: como de costumbre, mis habilidades de comunicación son insuficientes. Déjame aclarar.
Sé que el acceso a los elementos de la GUI a partir de hilos que no sean en los que fueron creados causa problemas. Sé que la forma correcta de acceder a ellos es a través de un delegado.
Mi pregunta era principalmente esta: ¿Por qué puedo acceder e iterar a través del objeto SelectedItems sin problemas, pero cuando trato de obtener (no establecer) la propiedad de Count de él, explota?
La propiedad Count de SelectedItems no es segura para subprocesos, por lo que no puede usarla de forma cruzada.
No puede acceder a los elementos de GUI desde un hilo separado. Use un delegado para hacer el cambio.
p.ej.
lblStatus.Invoke((Action)(() => lblStatus.Text = counter.ToString()));
o más viejo skool:
lblTest.Invoke((MethodInvoker)(delegate()
{
lblTest.Text = i.ToString();
}));
Tengo una publicación en el blog sobre cómo hacer esto en todos los lanzamientos de .Net aquí .
Porque creó un control en un hilo y está intentando alcanzarlo desde otro. Llame a la propiedad InvokeRequired como se muestra aquí:
private void RunMe()
{
if (!InvokeRequired)
{
myLabel.Text = "You pushed the button!";
}
else
{
Invoke(new ThreadStart(RunMe));
}
}
prgAll.Maximum = lbFolders.SelectedItems.Count;
En esa línea, realiza una asignación ( establecer / agregar ), que de forma predeterminada no es segura para subprocesos.
En la segunda línea, es solo una operación de obtención , donde la seguridad de la hebra simplemente no importa.
EDITAR: no me refiero al acceso al elemento prgAll.
El acceso a la propiedad Count cambia el estado interno de la colección interna de ListBox, por eso arroja la excepción.
Prueba esto:
private delegate void xThreadCallBack();
private void ThreadCallBack()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new xThreadCallBack(ThreadCallBack));
}
else
{
//do what you want
}
}
Sin embargo, la respuesta con la expresión lambda sería suficiente.
No puede tocar un objeto GUI desde un hilo que no es el hilo principal de la GUI. Mira aquí para más detalles y la solución.