簡體   English   中英

在 C# 中調用帶參數方法的最短方法

[英]Shortest way to invoke a method with parameters in 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});
}

這段代碼工作正常,但它很重。 我想在不聲明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});
}

如果您希望避免為每個調用創建委托類型,請使用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;的示例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
}));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM