2012-03-29 18 views
1

Ich habe zwei verschiedene Projekte und in einem, ich habe eine Klasse, die ein benutzerdefiniertes Ereignis definiert unter bestimmten Bedingungen Feuer:Benutzerdefinierte Ereignisse und Threading

public delegate void ButtonHandler(object myObject, 
              GuitarArgs myargs); 

     public event ButtonHandler OnButtonPress; 

... other stuff ... 

    GuitarArgs myArgs = new GuitarArgs(guitarState); 
       if(OnButtonPress!= null) 
        OnButtonPress(this, myArgs); 

Dann in einem anderen Projekt erstelle ich eine Instanz dieser Klasse und subscribe zu diesem Event:

Guitar.OnButtonPress += Guitar_OnButtonPress; 

Das Ereignis löst dann richtig, aber es scheint, auf einem anderen Thread zu sein, denn wenn ich versuche, einige UI-Elemente zuzugreifen, ich erhalte eine Fehlermeldung: Der rufende Thread dieses Objekt nicht zugreifen kann weil ein anderer Thread es besitzt.

Der Code der Fehler zu werfen ist:

void Guitar_OnButtonPress(object myObject, Guitar.GuitarArgs myargs) 
     { 
      GuitarCheck(myargs.State); 
     } 

     private void GuitarCheck(GuitarState getState) 
     { 
       if (getState.green) 
       { 
        VisualTreeHelper.HitTest(guitarCanvas, null, 
              MyHitTestResult, 
              new GeometryHitTestParameters(
               new RectangleGeometry(new Rect(1, 411, 88, 78)))); 
       } 
} 

Was kann ich tun, um diese zum Laufen zu bringen?

Vielen Dank.

+0

ähnliches Problem zu dieser Frage: http://stackoverflow.com/questions/2403972/c-sharp-events-between-threads-executed-in-their-own-thread-how-to –

Antwort

2

Sie müssen überprüfen, ob Ihre Event-Handler auf einem Nicht-UI-Thread ausgeführt wird, und wenn ja, rufen Sie es auf dem UI-Thread:

How to update the GUI from another thread in C#?

Ich möchte die weniger upvoted markieren Antwort, die einen sehr eleganten Ansatz unter Verwendung einer Erweiterungsmethode bietet. Ich benutze dies in alle meine WinForms-Projekte (und eine Variante in WPF/Silverlight-Projekte verwenden)

https://stackoverflow.com/a/3588137/141172

0

So haben Sie ein Ereignis namens OnButtonPress whos Event-Handler offensichtlich ausgeführt wird auf einem Thread, der nicht hostet VisualTreeHelper. Die große Frage ist für mich ... warum? Mit einem Namen wie OnButtonPress denke ich, dass es schon auf dem UI-Thread sein sollte. Afterall, es ist ein Knopfdruck richtig? Also warum ist es auf einem anderen Thread zu starten mit?

Verwenden eines Marshalling-Vorgangs wie Invoke oder BeginInvoke ist in Ordnung, solange Sie wissen, warum es benötigt wird und was es für Sie erreicht. Aber Sie müssen wirklich einen Schritt zurückgehen und herausfinden, was alles vor sich geht, was dazu führen würde, dass Sie benötigen, um zuerst einen Marshalling-Vorgang zu verwenden. Möglicherweise gibt es hier ein größeres Problem, das Sie ansprechen müssen.