1

Je développe une application s'exécutant sur un scanner de code-barres Windows Mobile 5. Parfois, je rencontre une exception de thread croisé provoquant l'échec de l'application.Exception de thread croisé lors de l'utilisation de Invoke()

L'application est écrite en C# 3.5 et est construite sur le dessus du Motorola EMDK pour .NET mais utilise également des parties du Smart Device Framework.

Dans mon formulaire principal, j'ai un Panel dans lequel je change le contenu en fonction du contexte de l'application. Toutes les vues partagent une interface commune IContentView.

J'utilise également des threads d'arrière-plan pour surveiller si le périphérique est en cours de charge (déclenche une déconnexion de l'utilisateur) et également surveiller si l'appareil peut se connecter au serveur.

J'utilise la construction John Skeets de here lors de l'appel des modifications du panneau, afin d'assurer des changements en cours sur le contrôle invoquées étant changé:

public void ShowContent(IContentView content) 
    { 
     contentPanel.Invoke(() => 
      { 
       contentPanel.Controls.Clear(); 
       contentPanel.Controls.Add(content as UserControl); 
       contentPanel.Focus(); 
      }); 
    } 

contentPanel étant un System.Windows.Forms.Panel.

Mais je reçois toujours l'exception suivante:

Control.Invoke must be used to interact with controls created on a separate thread. 
    at Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar) 
    at System.Windows.Forms.Control.get_Parent() 
    at System.Windows.Forms.Control.ControlCollection.Add(Control value) 
    at BarcodeScanner.MainView.MainForm.<>c__DisplayClass1e.<ShowContent>b__1d() 
    at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark) 
    at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess, StackCrawlMark& stackMark) 
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) 
    at System.Windows.Forms.Control.TASK.Invoke() 
    at System.Windows.Forms.Control._InvokeAll() 
    at System.Windows.Forms.Control.WnProc(WM wm, Int32 wParam, Int32 lParam) 
    at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) 
    at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain) 
    at System.Windows.Forms.Application.Run(Form fm) 
    at BarcodeScanner.Program.Main() 

Qu'est-ce que je manque ici? Ai-je besoin de faire autre chose pour rassembler les modifications correctement du fil au panneau?

Tout conseil est fortement apprécié.

+0

http://stackoverflow.com/questions/1423446/thread-control-invoke – EngineerSpock

+0

Eh bien, cela n'a manifestement pas résoudre le problème. Vous devez poster votre code * original * et votre trace de pile d'exception, ce que vous avez posté ici ne nous aide pas à vous aider. –

+0

assure que 'IContentView' qui semble être un' UserControl' a également été créé dans le thread principal. – Marwie

Répondre

2

Pour moi, il semble que le problème se produit lors de l'ajout de content as UserControl à Controls.

Vérifiez dans quel thread IContentView content a été créé, je suppose pas dans le thread principal, ce qui peut être le problème.

Regardez aussi ici: Why can you cross thread adding controls in WinForms, but not WPF?

Il semble que ce soit aussi « interdit » dans Windows Forms, mais pas aussi strictement contrôlé par le code-cadre.

Donc, la solution sera de créer tous les contrôles de l'interface graphique dans le thread principal, en utilisant probablement Invoke()

+0

Merci beaucoup. Je pense que tu es sur place ici. Certains UserControls définis sur le Panel (principalement ceux déclenchés par un événement) ont été construits en cas de besoin. Je l'ai modifié pour que tous les contrôles soient construits pendant le démarrage de l'application. Merci de m'avoir poussé dans la bonne direction. – Moelgaard