2010-10-31 8 views
1

J'ai un winform et quelques threads. Lorsque j'essaie d'accéder à un champ dans le winform à partir de l'un des threads, l'erreur suivante se produit: Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on.Accès aux données sur un autre thread

Comment puis-je résoudre ce problème?

Cordialement, Alexandru Badescu

+1

ou Invoke BeginInvoke – CodesInChaos

+1

double possible de [l'aide multithreading, encore une fois (Winforms)] (http://stackoverflow.com/questions/3999020/multithreading-help-yet-again-winforms) –

Répondre

4

Tous les contrôles ont une méthode appelée Invoke, qui prend un délégué comme premier argument et optionnel params object [].
Vous pouvez utiliser cette méthode facilement:

richTextBox1.Invoke(new MethodInvoker(DoSomething)); 

void DoSomething() 
{ 
    richTextBox1.BackColor = Color.Cyan; 
} 

Le délégué MethodInvoker est dans l'espace de noms System.Windows.Forms, qui, je suppose, que vous utilisez déjà.

Vous pouvez même invoquer à partir du même fil!

Vous pouvez également utiliser des paramètres, comme ceci:

richTextBox1.Invoke(new ColorChanger(DoSomething), Color.Cyan); 

delegate void ColorChanger(Color c); 

void DoSomething(Color c) 
{ 
    richTextBox1.BackColor = c; 
} 

J'espère que cela a aidé!

Modifier:
InvokeRequired est requis si vous utilisez la même méthode à partir d'un thread ... fondamentalement ... inconnu. Il ressemblerait à ceci:

void DoSomething() 
{ 
    if (richTextBox1.InvokeRequired) 
     richTextBox1.Invoke(new MethodInvoker(DoSomething)); 
    else 
    { 
     richTextBox1.BackColor = Color.Cyan; 
     // Here should go everything the method will do. 
    } 
} 

Vous pouvez appeler cette méthode à partir de fil!

Et pour les paramètres:

delegate void ColorChanger(Color c); 

void DoSomething(Color c) 
{ 
    if (richTextBox1.InvokeRequired) 
     richTextBox1.Invoke(new ColorChanger(DoSomething), c); 
    else 
    { 
     richTextBox1.BackColor = c; 
     // Here should go everything the method will do. 
    } 
} 

Profitez de programmation!

+0

Multumesc mult Vercas! : D Très détaillé! +1 – Alex

+0

oh et une autre question! pourquoi ces invocations sont-elles requises? Je veux dire, quel est le but de l'utilisation de ce genre d'invoquer? Pourquoi ne puis-je pas appeler directement? – Alex

2

Dans votre code de fil, avant de changer textBox1, vérifier textBox1.InvokeRequired et si oui, utilisez textBox1.Invoke(aDelegate)

+0

je vais chercher des liens, ce Q est un dupe. –

+0

donc j'ai utilisé le code suivant: « setText public void (String a) { si (this.richTextBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback (setText); this.Invoke (d, nouvel objet [] {a}); } { autre this.richTextBox1.Text = a; } ' }' – Alex

+0

ma question est, qu'est-ce que ce code signifie réellement? Qu'est ce que ça fait? – Alex

2

ce Vercas suggéré fonctionne très bien, mais si vous aimez le code en ligne vous pouvez aussi choisir un délégué anonyme

richTextBox1.Invoke(new MethodInvoker(
    delegate() { 
     richTextBox1.BackColor = Color.Cyan; 
    )); 

+1 lui :)

+0

Merci pour le +1! – Vercas

1

Alexandru Salut

Vous pouvez voulez vérifier une autre façon, le

BackgroundWorker

composant. C'est vraiment facile et confortable à utiliser.Plus de détails et des échantillons que vous pouvez trouver ici

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Ce composant est également très importante dans .NET et très utile de savoir.

+0

multumesc! Je vais regarder dedans! – Alex

+0

Même s'il utilisait un arrière-plan, il devait toujours utiliser cette méthode pour mettre à jour les contrôles. – Vercas

Questions connexes