在 C# 中调用带参数方法的最短方法

And*_*ewR 5 c#

当我需要在指定的线程中调用一些代码时,我使用的是这样的:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;

delegate void MethodToInvokeDelegate(string foo, int bar);

void MethodToInvoke(string foo, int bar)
{
    DoSomeWork(foo);
    DoMoreWork(bar); 
}

void SomeMethod()
{
    string S = "Some text";
    int I = 1;
    dispatcher.BeginInvoke(new MethodToInvokeDelegate(MethodToInvoke), new object[] {S, I});
}
Run Code Online (Sandbox Code Playgroud)

这段代码工作正常,但它很重。我想使它不宣MethodToInvokeMethodToInvokeDelegate-使用匿名方法。但是我不知道如何将参数传递给它。

我不能这样写:

dispatcher.BeginInvoke((Action)delegate() { DoSomeWork(S); DoMoreWork(I); });
Run Code Online (Sandbox Code Playgroud)

我需要实际将参数传递给方法。

有没有办法把它写得简短而简单?

例子:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
int[] ArrayToFill = new int[3];

void SomeMethod()
{
    for (int i = 0; i < 3; i++)
        dispatcher.BeginInvoke( { ArrayToFill[i] = 10; } );
}
Run Code Online (Sandbox Code Playgroud)

此代码将不起作用:将使用 i = 1、2、3 调用方法并将引发 IndexOutOfRange 异常。i将在方法开始执行之前递增。所以我们需要像这样重写它:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
int[] ArrayToFill = new int[3];

delegate void MethodToInvokeDelegate(int i);

void MethodToInvoke(int i)
{
    ArrayToFill[i] = 10; 
}

void SomeMethod()
{
    for (int i = 0; i < 3; i++)
         dispatcher.BeginInvoke(new MethodToInvokeDelegate(MethodToInvoke), new object[] {i});
}
Run Code Online (Sandbox Code Playgroud)

ASh*_*ASh 5

如果你想避免创建每个呼叫委托类型,利用Action<>Action<,>等等

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
string S = "Some text";
int I = 1;
dispatcher.BeginInvoke(
                        (Action<string, int>)((foo, bar) =>
                        {
                            MessageBox.Show(bar.ToString(), foo);
                            //DoSomeWork(foo);
                            //DoMoreWork(bar); 
                        }), 
                        new object[] { S, I }
                      );
Run Code Online (Sandbox Code Playgroud)

一个带有ArrayToFill[j] = 10;动作的示例可以非常简单地修复:

for (int i = 0; i < 3; i++)
{
    int j = i;
    // lambda captures int variable
    // use a new variable j for each lambda to avoid exceptions
    dispatcher.BeginInvoke(new Action(() =>
    {
        ArrayToFill[j] = 10;
    }));
}
Run Code Online (Sandbox Code Playgroud)