19

匿名メソッドをパラメーターとしてメソッドに渡せないのはなぜBeginInvokeですか? 次のコードがあります。

private delegate void CfgMnMnuDlg(DIServer svr);
private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu, 
                            new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}

デリゲートの宣言を避けようとしています。代わりに以下のようなものを書くことができないのはなぜですか? それとも、正しい構文を理解できないだけですか? 以下は現在、以下を生成します。

引数の型 '匿名メソッド' は、パラメーターの型 'System.Delegate' に割り当てることができません

もちろんその通りですが、これを行うために使用できる他の構文はありますBeginInvoke()か?

(これを行うことができれば、明示的なデリゲートの代わりにアノン メソッド/ラムダを使用するという概念にうまく適合し、他の場所でもきれいに機能します。)

private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke(  //  pass anonymous method instead ?
             delegate(DIServer svr) { ConfigureMainMenu(server);},     
             new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}
4

6 に答える 6

36

これを試して:

control.BeginInvoke((MethodInvoker) delegate { /* method details */ });

または:

private void ConfigureMainMenu(DIServer server)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(new Action<DIServer >(ConfigureMainMenu), server);
    }
    else
    {
        /* do work */
    }
}

または:

private void ConfigureMainMenu(DIServer server)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        // Private variable
        _methodInvoker = new MethodInvoker((Action)(() => ConfigureMainMenu(server)));
        _methodInvoker.BeginInvoke(new AsyncCallback(ProcessEnded), null); // Call _methodInvoker.EndInvoke in ProcessEnded
    }
    else
    {
        /* do work */
    }
}
于 2009-06-17T15:02:05.573 に答える
2

あなたはこのようなものを書くことができるはずです:

private void ConfigureMainMenu(DIServer server,)
{
    MenuStrip mnMnu = PresenterView.MainMenu;
    if (mnMnu.InvokeRequired)
    {
        mnMnu.BeginInvoke(new Action<DIServer>(ConfigureMainMenu), 
                            new object[] { server});
    }
    else
    {
        // Do actual work here
    }
}
于 2009-06-17T15:09:50.520 に答える
1

匿名メソッドをラップする拡張メソッドを記述し、InvokeRequiredセマンティクスを処理することもできます。

public static void InvokeAction(this Control ctl, Action a)
{
    if (!ctl.InvokeRequired)
    {
        a();
    }
    else
    {
        ctl.BeginInvoke(new MethodInvoker(a));
    }
}

これにより、次のことが可能になります。

control.InvokeAction(delegate() { ConfigureMainMenu(server); });
于 2009-06-17T15:14:27.827 に答える
1

自分自身を呼び出して呼び出すことにより、単一のメソッドでこれを行うことができます。

  ClassData updData =  new ClassData();

  this.BeginInvoke(new Action<ClassData>(FillCurve),
                           new object[] { updData });

...

public void FillCurve(ClassData updData)
{
 ...
}
于 2014-09-24T18:05:25.277 に答える
0

限られた数のパラメーターを持つ完全に匿名のメソッドの場合:

Func<int, int?> caller = new Func<int, int?>((int param1) =>
   {
      return null;
   });

caller.BeginInvoke(7, new AsyncCallback((IAsyncResult ar) =>
{
   AsyncResult result = (AsyncResult)ar;
   Func<int, int?> action = (Func<int, int?>)result.AsyncDelegate;
   action.EndInvoke(ar);
}), null);

必要に応じて、他の Func デリゲート型のいずれかを使用できます。

于 2009-09-25T03:36:31.600 に答える
0

さまざまな方法を試しましたが、どれもうまくいきません。つまり...


// Fails -- cannot convert lamda to System.Delegate
mnMnu.BeginInvoke( (DIServer svr)=> {ConfigureMainMenu(server);}, new object[] server);
// Fails -- cannot convert anonymous method to System.Delegate
mnMnu.BeginInvoke( new delegate(DIServer svr){ConfigureMainMenu(server);}, new object[] server);

したがって、短い答えはノーです。特定のコンテキストで短いヘルパー デリゲートを作成し、ラムダを使用して少しすっきりさせることもできますが、それだけです。

編集:私が間違っていることがわかりました。以下の methodinvoker の回答が機能します。このページを見る

于 2009-06-17T14:45:39.147 に答える