1

I can't use eventArgs from a method trigged for a second 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 });
            .
            .
            .
        }
    }   
}

Works fine, but when I try use "sender" and "e" event args in user method (in main thread), the message bellow appears: "The calling thread cannot access this object because a different thread owns it."

Can someone give me a hint about this problem? Thanks,

Jeferson


Follow Tudor, thanks again. This code is in window.xaml.cs code. The code in first post is 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();
}
  • Please add Java or another language tag to the question. – Gray Mar 30 '12 at 18:08
  • 3
    This is WPF keeping you out of trouble, reminding you that you are trying to access an object that is not thread-safe from another thread. You can't. – Hans Passant Mar 30 '12 at 18:13
  • It is as if the secondary thread "catch" the user method to her: the user metod don't execute any command with window components. I search for a form to call a main thread method from secondary thread. – Jeferson Preti Mar 30 '12 at 19:06
  • @Jeferson Preti: Which GUI control are you changing from the thread? What's the name of the variable? – Tudor Mar 30 '12 at 19:16
  • @Tudor: the communication thread (secondary) checks in external hardware if a particular variable are changed. If yes, "sender" receive the variable address and "e" receive previous e actual value of variable. When it's happen, a method in main thread must be called to made actions in wpf window (alarms warnings, etc). This method, must be change GUIs (in this time, just a label content), but the error appears. The method are trigged, but, apparently, does not belong to main thread any more. Thanks. – Jeferson Preti Mar 30 '12 at 19:38
  • @Jeferson Preti: Can you please post the code that gets executed when you call `onWatchParameterMethod`? – Tudor Mar 30 '12 at 19:40
  • @Tudor: I put the code in end of first post (I don't answer my own question in last 6 hours, :). Thanks a lot for attention! – Jeferson Preti Mar 30 '12 at 20:01
  • @Jeferson Preti: Check my answer. – Tudor Mar 30 '12 at 20:20

3 Answers3

0

Thanks a lot, this works fine

if (this.InvokeRequired)
{
  BeginInvoke(new MethodInvoker(delegate()
  {
    printausfueren();
  }));
}
else
{
     printausfueren();
}
ovonel
  • 9
  • 1
0

if your application is winforms, you can do this

    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 this example, d and foo are located in the form's class

Odys
  • 8,951
  • 10
  • 69
  • 111
  • Hi thanks for answer. The project is in WPF. I try change Dispatcher.CurrentDispatcher.Invoke for Dispatcher.CurrentDispatcher.BeginInvoke but the error remains the same. More tips are welcome :), thanks again. – Jeferson Preti Mar 30 '12 at 18:40
0

The label update needs to be done via Dispatcher.BeginInvoke:

private void getChangeParameters_Movilink(ParameterAddress sender, MovilinkEventArgs e)
{
    label24.Dispatcher.BeginInvoke(
       (Action)(() =>
       {
          label24.Content = e.ActualValue.ToString();
       }));
}
Tudor
  • 61,523
  • 12
  • 102
  • 142
  • @Jeferson Preti: You're welcome. Don't forget to accept the answer if it solved your problem. :) – Tudor Mar 30 '12 at 20:37