2012-03-30 10 views
1

ich nicht EventArgs von einem Verfahren trigged für ein zweites Gewinde verwenden:Invoke Methoden in einem Thread

public class MovilinkCommunication 
{ 
    //Method Declarations 
    public delegate void MovilinkWatchParametersEventMethod(ParameterAddress sender, MovilinkEventArgs e); 
    private MovilinkWatchParametersEventMethod onWatchParameterMethod; 

    //class constructor 
    //here, the user inputs the method (in main thread) that desires to call in 
    //parameter changed moment 
    public MovilinkCommunication(MovilinkWatchParametersEventMethod userOnWatchParameterMethod) 
    { 
     //assign user method (in main thread) to wach variables 
     onWatchParameterMethod = userOnWatchParameterMethod; 

     //start communication thread (second thread) 
     Thread movilinkThread = new Thread(new ThreadStart(movilinkIOManagerThread)); 
     movilinkThread.Start(); 
    } 
    . 
    . 
    . 
    //create delegates with "sender" parameter and "e" conditions of call 
    delegate void CallOnWatchParameterMethod(ParameterAddress sender, MovilinkEventArgs e); 
    private void callOnWatchParameterMethod(ParameterAddress sender, MovilinkEventArgs e) 
    { 
     //calling user method in main thread with event args obtained in 
     //communication thread (second thread) 
     onWatchParameterMethod(sender, e); 
    } 
    . 
    . 
    . 
    //communication thread 
    private void movilinkIOManagerThread() 
    { 
     ParameterAddress sender; 
     MovilinkEventArgs e; 
     . 
     . 
     . 
     while (movilinkAccessor.OperationStatusOk) 
     { 
      . 
      . 
      . 
      CallOnWatchParameterMethod thdCallOnWatchParameterMethod = 
       new CallOnWatchParameterMethod(callOnWatchParameterMethod); 

      Dispatcher.CurrentDispatcher.Invoke(thdCallOnWatchParameterMethod, new object[] { sender, e }); 
      . 
      . 
      . 
     } 
    } 
} 

funktioniert gut, aber wenn ich versuche, "Sender" und "e" event args in Benutzer-Methode verwenden, (im Hauptthread) erscheint die folgende Meldung: "Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da ein anderer Thread es besitzt."

Kann mir jemand einen Hinweis auf dieses Problem geben? Danke,

Jeferson


Follow Tudor, nochmals vielen Dank. Dieser Code befindet sich in window.xaml.cs-Code. Der Code im ersten Post ist in MovilinkComunication.cs.

MovilinkCommunication comunicadorMovilink; 
private void wndPrincipal_Loaded(object sender, RoutedEventArgs e) 
{ 
    //creating communication object, setting the desired event 
    //to be trigged in secundary thread 
    comunicadorMovilink = 
     new MovilinkCommunication(getChangeParameters_Movilink); 
}   
. 
. 
. 
//desired method to made actions in window, if detected 
//change of parameters in external hardware 
private void getChangeParameters_Movilink(ParameterAddress sender, MovilinkEventArgs e) 
{ 
    //error occurs here. Any code with GUI return error. 
    label24.Content = e.ActualValue.ToString(); 
} 
+0

Bitte fügen Sie Java oder ein anderes Sprach-Tag zu der Frage hinzu. – Gray

+3

Dies ist WPF, das Sie vor Ärger bewahrt, indem Sie daran erinnert werden, dass Sie versuchen, auf ein Objekt zuzugreifen, das nicht Thread-sicher von einem anderen Thread ist. Du kannst nicht. –

+0

Es ist, als ob der sekundäre Thread die Benutzermethode zu ihr "abfängt": Der Benutzer metod führt keinen Befehl mit Fensterkomponenten aus. Ich suche nach einem Formular, um eine Haupt-Thread-Methode aus dem sekundären Thread aufzurufen. –

Antwort

0

Das Label Update über Dispatcher.BeginInvoke getan werden muss, :

private void getChangeParameters_Movilink(ParameterAddress sender, MovilinkEventArgs e) 
{ 
    label24.Dispatcher.BeginInvoke(
     (Action)(() => 
     { 
      label24.Content = e.ActualValue.ToString(); 
     })); 
} 
+0

Ist es Tudor? Danke, vielen Dank! Gott segne dich. –

+0

@Jeferson Preti: Gern geschehen. Vergiss nicht, die Antwort zu akzeptieren, wenn es dein Problem gelöst hat. :) – Tudor

0

, wenn Ihre Anwendung WinForms ist, können Sie dies tun

public void d() 
    { 
     if (this.InvokeRequired) 
     { 
      BeginInvoke(new MethodInvoker(delegate() { 
       foo(a, b); 
      })); 
     } 
     else 
     { 
      foo(a, b); 
     } 
    } 

    private void foo(int a, int b) 
    { 

    } 

in diesem Beispiel d und foo werden in Form der Klasse befindet

+0

Hallo Danke für die Antwort. Das Projekt ist in WPF. Ich versuche, Dispatcher.CurrentDispatcher.Invoke für Dispatcher.CurrentDispatcher.BeginInvoke zu ändern, aber der Fehler bleibt gleich. Weitere Tipps sind willkommen :), nochmals vielen Dank. –

0

Dank a Lot, das funktioniert gut

if (this.InvokeRequired) 
{ 
    BeginInvoke(new MethodInvoker(delegate() 
    { 
    printausfueren(); 
    })); 
} 
else 
{ 
    printausfueren(); 
} 
Verwandte Themen