在特定线程中执行方法/设置属性

时间:2011-05-03 16:04:54

标签: c# .net multithreading invoke

大家好 我对所有这些多线程的东西都是新手,所以如果我解释得很糟,请原谅我:)

假设我有两个班级:

class abc {
    public string SomeProperty {
        get { return something; }
        set { /* This code has to execute in the main application thread */ }
    }

    public void SomeMethod() {
        /* This code also has to execute in the main application thread */
    }
}

class def {
    abc obj;

    public def() {
        abc = new obj();
    }

    public void SomeMethod() {
        abc.SomeProperty = "SomeValue";
        abc.SomeMethod();
    }
}

我遇到的问题是让SomeProperty和SomeMethod在主应用程序线程上执行。我试过了:

abc.GetType().InvokeMember("SomeProperty", System.Reflection.BindingFlags.SetProperty, null, abc, new object[] { "SomeValue" });
abc.GetType().InvokeMember("SomeMethod", System.Reflection.BindingFlags.InvokeMethod, null, abc, null);

然而,即使使用InvokeMember,我也不会在主应用程序线程中执行需要在主应用程序线程中执行的代码(我不这么认为) 我已经尝试在代码中输出当前线程名称,并且它不输出主应用程序线程名称。

有没有办法可以做到这一点? 如果我已经解释得很糟糕,请告诉我:) 谢谢!

2 个答案:

答案 0 :(得分:2)

有多种方法可以做到这一点,但我的首选方法如下:

   protected void setTransactionButton(Boolean enabled)
    {
        (new Task(() =>
        {
            transcriptQuitButton.Enabled = enabled;
        })).Start(uiScheduler);
    }

在我的初始化代码中,我称之为:

uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

这样做是为了让事件发生在UI线程上,并且不再需要BeginInvoke

BeginInvoke有很多可以找到的地方,但是如果你可以使用匿名函数,那么就有一篇文章在这里:

http://visualstudiomagazine.com/articles/2009/02/01/use-lambda-expressions-for-abstract-delegates.aspx

答案 1 :(得分:1)

InvokeMember只是使用反射执行成员的一种方式。它与线程无关。

我怀疑你真的在寻找Control.InvokeDispatcher.Invoke(或非阻塞BeginInvoke等价物。)

当然,您需要对适当的控件或调度程序的引用,然后创建一个适当的委托以在另一个线程上执行。如果您在Windows Forms多线程(或WPF)上寻找教程,您应该找到很多示例。 (我的网络连接目前是垃圾,否则我会为你找到一个不错的。)

编辑:现在您已经明确了它是一个控制台应用程序,您将不得不找出某种形式的消息泵。除非线程以某种方式监听消息,否则无法强制它执行另一段代码。我没有使用过你所谈过的库 - 但如果它强迫你在特定的线程上执行代码,那么它应该提供一些等价的Control.Invoke等。