C# 方法或扩展方法来处理InvokeRequired

C# 方法或扩展方法来处理InvokeRequired,c#,winforms,events,delegates,extension-methods,C#,Winforms,Events,Delegates,Extension Methods,我还不能想出一个解决方案来创建一个通用方法来处理void方法所需的invokererequired(稍后我将处理返回值)。我的想法是: // Probably not the best name, any ideas? :) public static void CheckInvoke(this Control instance, ,Action<object, object> action) { if (instan

我还不能想出一个解决方案来创建一个通用方法来处理void方法所需的
invokererequired
(稍后我将处理返回值)。我的想法是:

// Probably not the best name, any ideas? :)
public static void CheckInvoke(this Control instance,
                               ,Action<object, object> action)
{
  if (instance.InvokeRequired)
  {
    instance.Invoke(new MethodInvoker(() => action));
  }
  else
  {
    action()
  }
}
public partial class MyForm : Form
{
  private ThreadedClass c = new ThreadedClass();

  public MyForm()
  {
    c.ThreadedEvent += this.CheckInvoke(this
                                        ,this.MethodRequiresInvoke
                                        ,sender
                                        ,e);
  }
}

这显然不是编译的,我只是不能很好地将其结合起来。

Hans是正确的,因为您可能不想像这样包装代码,特别是因为它可能会在确定线程上正在发生的操作时引起一些调试问题。也就是说,这将是您想要的签名:

public static class FormsExt
{
    public static void UnwiseInvoke(this Control instance, Action toDo)
    {
        if(instance.InvokeRequired)
        {
            instance.Invoke(toDo);
        }
        else
        {
            toDo();
        }
    }
}

松开“object,object”的操作参数(正如JerKimball所建议的),将其命名为SafeInvoke,并通过匿名委托附加到事件:

 c.ThreadedEvent += delegate
                        {
                           c.SafeInvoke(this.MethodRequiresInvoke);
                        };

你为什么要写这样的代码?你知道你必须使用invoke,为什么还要麻烦检查它呢?被调用的方法要么是我的线程类(我无法控制)要么是我自己的代码。只是对同一个问题的进一步讨论:这只是问题的一半,因为我无法将事件连接到扩展方法。在这种情况下,由于它需要一个通用操作,所以您必须:c.ThreadedEvent+=(o,e)=>this.UnwiseInvoke(()=>{do stuff});我建议最好在ISynchronizeInvoke上创建一个扩展方法,而不是控件。我不打算用这个。其想法是制作一个简单、可读和可维护的通用方法,但在这种情况下,我之后的任何程序员都会想自杀。(但它确实有效!)选择得很好-这是您将看到重复的代码,您可以提出这样的论点,即您编写两次以上的任何代码都应该封装起来,但在这种情况下,缺点(以及混淆的复杂性)是一个强大的参数,不执行此操作。这似乎不起作用,因为委托与事件委托签名不匹配。它确实起作用,因为参数列表是可选的。我已经在4.5上编译/运行了这样的示例,我正在使用4.0,这是问题所在吗?它从2.0开始工作。这不起作用
This.comboBox1.ChangeUICues+=delegate(){}这项工作
This.comboBox1.ChangeUICues+=委托{}