Ho sofferto per un po 'di tempo: Ho una funzione progettata per aggiungere il controllo a un pannello con gestione cross-thread, il problema è che sebbene il pannello e il controllo sono in "InvokeRequired = false" - Ricevo un'eccezione che mi dice che uno dei controlli interni dei controlli è accessibile da un thread diverso dal thread su cui è stato creato, lo snippet va in questo modo:Eccezione "cross-thread operation not valid" sui controlli interni
public delegate void AddControlToPanelDlgt(Panel panel, Control ctrl);
public void AddControlToPanel(Panel panel, Control ctrl)
{
if (panel.InvokeRequired)
{
panel.Invoke(new AddControlToPanelDlgt(AddControlToPanel),panel,ctrl);
return;
}
if (ctrl.InvokeRequired)
{
ctrl.Invoke(new AddControlToPanelDlgt(AddControlToPanel),panel,ctrl);
return;
}
panel.Controls.Add(ctrl); //<-- here is where the exception is raised
}
il messaggio di eccezione va in questo modo:
"Cross- operazione thread non valida: controllo 'pnlFoo' si accede da un thread diverso dal thread è stato creato su"
('pnlFoo' è sotto ctrl.Controls)
Come posso aggiungere ctrl al pannello? !
Quando il codice raggiunge "panel.Controls.Add (ctrl);" line - sia panel che ctrl La proprietà "InvokeRequired" è impostata su false, il problema è che i controlli all'interno di ctrl hanno impostato "InvokeRequired" su true. Per chiarire le cose: "pannello" viene creato sul thread di base e "ctrl" sul nuovo thread, quindi, "panel" deve essere invocato (facendo in modo che "ctrl" abbia bisogno di richiamare di nuovo). Una volta che entrambi i richiami sono terminati, raggiunge il comando panel.Controls.Add (ctrl) (sia "panel" che "ctrl" non ha bisogno di invocazione in questo stato)
Ecco un piccolo frammento del completo programma:
public class ucFoo : UserControl
{
private Panel pnlFoo = new Panel();
public ucFoo()
{
this.Controls.Add(pnlFoo);
}
}
public class ucFoo2 : UserControl
{
private Panel pnlFooContainer = new Panel();
public ucFoo2()
{
this.Controls.Add(pnlFooContainer);
Thread t = new Thread(new ThreadStart(AddFooControlToFooConatiner());
t.Start()
}
private AddFooControlToFooConatiner()
{
ucFoo foo = new ucFoo();
this.pnlFooContainer.Controls.Add(ucFoo); //<-- this is where the exception is raised
}
}
Ecco il programma: classe pubblica ucFoo: UserControl { panel privato pnlFoo = new Panel(); public ucFoo() { this.Controls.Add (pnlFoo); } } classe pubblica ucFoo2: UserControl { panel privato pnlFooContainer = new Panel(); public ucFoo2() { this.Controls.Add (pnlFooContainer); Thread t = new Thread (new ThreadStartAddFooControlToFooConatiner()); t.Start(); } private AddFooControlToFooConatiner() { ucFoo foo = new ucFoo(); this.pnlFooContainer.Controls.Add (ucFoo); // <- ecco dove viene sollevata l'eccezione } } – Nissim
Ho aggiunto lo snippet come risposta per una lettura migliore – Nissim