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

本文关键字:方法 参数 调用 | 更新日期: 2023-09-27 18:31:07

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

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});
}

这段代码工作正常,但它很重。我想在不声明MethodToInvokeMethodToInvokeDelegate的情况下做到这一点 - 使用匿名方法。但是我不知道如何将参数传递给它。

我不能这样写:

dispatcher.BeginInvoke((Action)delegate() { DoSomeWork(S); DoMoreWork(I); });

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

有什么方法可以写得简短而简单吗?

例:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
int[] ArrayToFill = new int[3];
void SomeMethod()
{
    for (int i = 0; i < 3; i++)
        dispatcher.BeginInvoke( { ArrayToFill[i] = 10; } );
}

此代码将不起作用:方法将在 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});
}

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

如果您希望避免为每个调用创建委托类型,请使用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 }
                      );

一个具有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;
    }));
}

试试这个:

string S = "Some text";
int I = 1;
dispatcher.BeginInvoke(new Action(() =>
{
    DoSomeWork(S);
    DoMoreWork(I);
}));

[编辑]

针对您修改后的问题:

您看到的问题是修改后的关闭问题。

要修复它,您只需在调用该方法之前复制参数:

Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
int[] ArrayToFill = new int[3];
for (int i = 0; i < 3; i++)
{
    int index = i;
    dispatcher.BeginInvoke(new Action(() => { ArrayToFill[index] = 10; } ));
}
yourUIcontrol.BeginInvoke(new MethodInvoker(delegate {
    //your code goes here
}));