【问题标题】:Invoke methods in a thread在线程中调用方法
【发布时间】:2012-03-30 18:05:51
【问题描述】:

我无法从为第二个线程触发的方法中使用 eventArgs:

 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 });
            .
            .
            .
        }
    }   
}

工作正常,但是当我尝试在用户方法(在主线程中)中使用“sender”和“e”事件参数时,会出现以下消息: “调用线程无法访问此对象,因为不同的线程拥有它。”

有人可以给我关于这个问题的提示吗?谢谢,

杰斐逊


关注都铎王朝,再次感谢。此代码位于 window.xaml.cs 代码中。第一篇文章的代码在 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();
}

【问题讨论】:

  • 请在问题中添加 Java 或其他语言标签。
  • 这是 WPF 让您远离麻烦,提醒您正在尝试从另一个线程访问不是线程安全的对象。你不能。
  • 就好像辅助线程“抓住”了她的用户方法:用户方法不执行任何带有窗口组件的命令。我搜索了一个表单来从辅助线程调用主线程方法。
  • @Jeferson Preti:您要从线程中更改哪个 GUI 控件?变量名是什么?
  • @Tudor:通信线程(辅助)检查外部硬件是否更改了特定变量。如果是,“sender”接收变量地址,“e”接收变量的前一个 e 实际值。发生这种情况时,必须调用主线程中的方法以在 wpf 窗口中执行操作(警报警告等)。这个方法,必须改GUI(此时只是一个标签内容),但出现错误。该方法被触发,但显然不再属于主线程。谢谢。

标签: c# multithreading invoke eventargs


【解决方案1】:

标签更新需要通过Dispatcher.BeginInvoke

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

【讨论】:

  • @Jeferson Preti:不客气。如果它解决了您的问题,请不要忘记接受答案。 :)
【解决方案2】:

如果你的应用是winforms,你可以这样做

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

    private void foo(int a, int b)
    {

    }

在本例中,dfoo 位于表单的类中

【讨论】:

  • 您好,感谢您的回答。该项目在WPF中。我尝试将 Dispatcher.CurrentDispatcher.Invoke 更改为 Dispatcher.CurrentDispatcher.BeginInvoke 但错误仍然相同。欢迎提供更多提示:),再次感谢。
【解决方案3】:

非常感谢,这很好用

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

【讨论】:

    猜你喜欢
    • 2019-10-20
    • 2011-12-22
    • 1970-01-01
    • 2017-10-29
    • 2013-03-29
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多