匿名メソッドをパラメーターとして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
}
}
_
これを試して:
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 */
}
}
あなたはこのような何かを書くことができるはずです:
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
}
}
匿名メソッドをラップする拡張メソッドを記述し、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); });
自分自身を呼び出すことを呼び出すことにより、単一のメソッドでこれを行うことができます。
ClassData updData = new ClassData();
this.BeginInvoke(new Action<ClassData>(FillCurve),
new object[] { updData });
.。
public void FillCurve(ClassData updData)
{
...
}
さまざまな方法を試しましたが、うまくいきません。すなわち.。
// 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の回答は機能します。これを参照してください ページ
パラメータの数が限られている完全に匿名のメソッドの場合:
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デリゲートタイプの1つを使用できます。