【问题标题】:Can you use pre-defined Action<T> in Control.BeginInvoke您可以在 Control.BeginInvoke 中使用预定义的 Action<T>
【发布时间】:2012-02-13 12:28:46
【问题描述】:

我有一些线程检查,我可以通过调用 BeginInvoke(new Action&lt;string,string&gt;........ 来完成以下工作,但我想知道您是否可以以某种方式使用预定义的操作?

private Action<string, string> DoSomething();

private void MakeItHappen(string InputA, string InputB)
{
  if (this.InvokeRequired)
  {
    this.BeginInvoke(DoSomething(InputA, InputB));
  }
  else
  {
     Label.Text = "Done";
     MyOtherGUIItem.Visible = false;
  }

}

【问题讨论】:

  • “预定义操作”是什么意思?
  • 它预定义为私有字段而不是执行 new Action

标签: c# .net multithreading .net-4.0 delegates


【解决方案1】:

如果我理解正确,你想要这样的东西吗?

private delegate void updateDelegate(string p1, string p2);
private updateDelegate DoSomething;

private void MakeItHappen(string InputA, string InputB)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(DoSomething, InputA, InputB);
    }
    else
    {
        //Do stuff
    }
}

【讨论】:

  • 是的,但它如何知道在 MakeItHappen 方法放入正确的线程后如何返回?
  • BeginInvoke 的调用是非阻塞的。在方法排队到 GUI 线程后,调用立即返回到 MakeItHappen 方法。
  • 我已经更新了我的问题,表明我想在 BeginInvoke 之后修改一些控件
  • @Jon,现在我明白了。不幸的是,当你声明它时,你不能让DoSomething 指向MakeItHappen,因为它要求方法是静态的,所以你不能使用this。为什么this.BeginInvoke(new Action...); 不可接受?
  • 是的,我只是想如果我有一组预定义的动作,我可以在整个代码库中使用它们。
【解决方案2】:

这是你的意思吗?

private Action<string, string> _DoSomething;

public void ConfigureToSecondThanFirstByExistingFunction()
{
    _DoSomething = MyMakeItLowerImplementation;
}

public void ConfigureToFirstThenSecondByLambda()
{
    _DoSomething = (a, b) => Console.WriteLine(a + b);
}

public void CallMe()
{
    ConfigureToSecondThanFirstByExistingFunction();
    //ConfigureToFirstThenSecondByLambda();

    _DoSomething("first", "second");
}

private void MyMakeItLowerImplementation(string a, string b)
{
    Console.WriteLine(b + a);
}

【讨论】:

  • 我想他想要一个有两个字符串参数并且没有返回值的方法。这里定义的Func是一个带有一个字符串参数和一个字符串结果的方法。
  • @Tudor:是的,但概念保持不变。我现在简单地重写了它。
【解决方案3】:

你必须将一个普通的delegate 传递给BeginInvoke。您可以使用变量捕获来包装您的参数,如下所示:

private void MakeItHappen(string InputA, string InputB)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke((Action)delegate () { 
            MakeItHappen(InputA, InputB); 
        });
    }
    else
    {
        // do stuff with InputA and InputB
    }
}

【讨论】:

  • 是的,但它如何知道在 MakeItHappen 方法放入正确的线程后如何返回?
  • private Action&lt;string, string&gt; DoSomething; 行将无法编译。
  • 执行不会回到MakeItHappen。您传递给 BeginInvoke 的委托只是在 UI 线程上异步执行。
  • 因为Action类只能带一个类型参数。
  • 对不起,我错了,我不小心瞄准了 .NET 2.0。道歉。
【解决方案4】:

这样吗?:

private delegate void DoSomethingHandler(string A, string B);
private event DoSomethingHandler DoSomething;

public void Start()
{
   DoSomething = (a, b) => { /*doStuff*/ };
}

private void MakeItHappen(string InputA, string InputB)
{
  if (this.InvokeRequired)
  {
    this.BeginInvoke(DoSomething, InputA, InputB);
  }
  else
  {
    //Do stuff
  }    
}

【讨论】:

  • 好的,我明白了,那么你需要一个代表
  • 抱歉,我不小心针对 .NET 2.0。在 4.0 中它可以编译。
猜你喜欢
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 2020-08-28
相关资源
最近更新 更多