2010-04-06 5 views
4

J'ai récemment mis à jour une application de VS2003 à VS2008 et je savais que je ferais face à une foule de "opération croisée pas valide: Contrôle 'myControl' accédé à partir d'un thread autre que le fil il était créé sur "Je gère cela dans ce que je crois est la bonne façon (voir l'exemple de code ci-dessous). Je cours dans de nombreux contrôles qui vont avoir besoin d'une solution similaire. Ne voulant pas avoir un code similaire pour chaque label, textbox etc. auquel un thread non UI accède. Quelles sont les ramifications de simplement définir le CheckForIllegalCrossThreadCalls = false pour l'application entière?Ramifications de CheckForIllegalCrossThreadCalls = false

J'ai trouvé un article CodeProject avec diverses solutions de contournement et un avertissement en bas pour ne pas définir la propriété. Je suis à la recherche d'autres opinions/expériences sur ce sujet.

private void ShowStatus(string szStatus) 
{ 
    try 
    { 
     if (this.statusBar1.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { ShowStatus(szStatus); })); } 
     else { statusBar1.Panels[0].Text = szStatus; } 
    } 
    catch (Exception ex) 
    { 
    LogStatus.WriteErrorLog(ex, "Error", "frmMNI.ShowStatus()"); 
    } 
} 

Je trouve un autre article avec quelques solutions possibles SO Question 2367718

Répondre

5

Lorsque vous n'êtes pas le débogage, vous aurez encore des problèmes.

la documentation De Control.CheckForIllegalCrossThreadCalls:

Notez que les appels illégaux contre-fil soulèvera toujours une exception lorsqu'une application est lancée en dehors du débogueur.

Vous devrez corriger les problèmes.

Cela dit, vous avez mentionné:

Ne voulant pas avoir un code similaire pour chaque étiquette, etc .. textbox qui sont accessibles par un fil non d'interface utilisateur.

Je reviendrais sur cette position. Vous devriez essayer de déplacer la logique qui s'exécute sur un thread séparé dans des méthodes ou des classes séparées, ce qui rendra le retour des appels dans l'interface utilisateur beaucoup plus simple. Au fil du temps, cela rendra votre code beaucoup plus fiable et maintenable.

Notez que vous pouvez utiliser Control.Invoke pour rassembler un ensemble d'appels à l'interface utilisateur en même temps, au lieu d'effectuer chaque opération individuellement. Il ne devrait vraiment pas y en avoir autant, quand vous aurez fini.

Edit:

Par exemple, il semble que vous chargez les données. Disons que vous avez (sur votre fil d'arrière-plan), votre méthode de chargement des données:

var myData = LoadData(); 
this.Invoke(new Action(() => 
    { 
     // Just set all of your data in one shot here... 
     this.textBox1.Text = myData.FirstName; 
     this.textBox2.Text = myData.LastName; 
     this.textBox3.Text = myData.NumberOfSales.ToString(); 
    })); 
+0

+1 - J'ai eu que très citation sur mon presse-papiers, quand je rafraîchi la page avant de poster une réponse ... –

+0

Control.Invoke semble être ce que je cherche. J'ai des données qui reviennent sur un thread NON-UI et définissant une douzaine de boîtes de texte, étiquettes, etc .. Si je pouvais le rassembler en un balayage ce serait génial. –

+0

@Ron: Oui, vous pouvez rassembler tout le code de l'interface utilisateur en un seul balayage. Utiliser la syntaxe lambda (puisque vous êtes dans VS2008) vous permet de le faire "en ligne" dans votre méthode, et pas besoin de faire un délégué bizarre à passer, aussi ... –

3

La section des remarques du documentation for CheckForIllegalCrossThreadCalls fait assez clair que cela est pas une bonne idée

Quand un thread autre que le créer thread d'un contrôle tente d'accéder l'une des méthodes de ce contrôle ou propriétés , il conduit souvent à des résultats imprévisibles. Une activité de threads non valide est un appel sur le thread incorrect qui accède à la propriété Handle du contrôle . Définissez CheckForIllegalCrossThreadCalls sur true pour trouver et diagnostiquer cette activité plus facilement lors du débogage. Notez que les appels de threads illégaux lèvent toujours une exception lorsqu'une application est démarrée en dehors du débogueur .

Questions connexes