使用不带Invoke的MethodInvoker

Neb*_*ula 4 c# lambda user-interface multithreading

我现在正在编写GUI应用程序一段时间,我总是使用一个方法是使用MethodInvoker + lambda函数来进行跨线程访问.

从示例中我发现我总是看到这样的东西:

版本1

if (InvokeRequired)
{
    Invoke(new MethodInvoker(() => 
    {
        Label1.Text = "Foobar";
    });
}
else
{
    Label1.Text = "Foobar";
}
Run Code Online (Sandbox Code Playgroud)

然而,这会导致代码重复 - >对我来说是主要的坏人.

那有什么不对呢?

版本2

MethodInvoker updateText = new MethodInvoker(() => 
    {
        Label1.Text = "Foobar";
    });

if (InvokeRequired)
{
    Invoke(updateText);
}
else
{
    updateText();
}
Run Code Online (Sandbox Code Playgroud)

现在我将功能捆绑在一个变量中,并在适当时使用Invoke或函数指针调用它.版本2的性能更差吗?或者我使用匿名函数是不好的做法?

Jon*_*eet 10

它没有什么问题......但你可以添加一个扩展方法,使它更好一些:

public static void InvokeIfNecessary(this Control control,
                                     MethodInvoker action)
{
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

this.InvokeIfNecessary(() => Label1.Text = "Foobar");
Run Code Online (Sandbox Code Playgroud)

更整洁:)

在不需要时创建委托会有一个非常轻微的性能缺陷,但几乎肯定无关紧要 - 专注于编写干净的代码.

请注意,即使您不想这样做,您仍然可以在现有代码中使变量声明更简单:

MethodInvoker updateText = () => Label1.Text = "Foobar";
Run Code Online (Sandbox Code Playgroud)

这是使用单独变量的一个好处 - 您不需要该new MethodInvoker位来告诉lambda表达式您想要什么类型的委托...