Dispatcher.BeginInvoke:ラムダをSystem.Delegateに変換できません


82

電話をかけようとしていますSystem.Windows.Threading.Dispatcher.BeginInvoke。メソッドのシグネチャは次のとおりです。

BeginInvoke(Delegate method, params object[] args)

デリゲートを作成する代わりに、ラムダを渡そうとしています。

_dispatcher.BeginInvoke((sender) => { DoSomething(); }, new object[] { this } );

コンパイラエラーが発生し、

ラムダをSystem.Delegateに変換できません。

デリゲートの署名は、オブジェクトをパラメーターとして受け取り、voidを返します。私のラムダはこれと一致しますが、機能していません。何が足りないのですか?

回答:


71

このメソッドはSystem.Delegateを受け取るため、そのように宣言された特定のタイプのデリゲートを指定する必要があります。これは、次のように、キャストまたは新しいDelegateTypeを介した指定されたデリゲートの作成を介して実行できます。

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     new object[] { this } 
  );

また、SLaksが指摘しているように、Dispatcher.BeginInvokeはparams配列を受け取るため、次のように記述できます。

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     this
  );

または、DoSomethingがこのオブジェクト自体のメソッドである場合:

_dispatcher.BeginInvoke(new Action(this.DoSomething));

3
しかし、そうではありません(x)=> {DoSomething(); }代理人の署名と一致しますか?指定する必要があるのはそれだけだと思いました。
ミカ2011

@Micah:System.Delegateには署名がありません。これは、単なる「任意のデリゲート」です。デリゲートタイプにsigを指定する必要があります。それはあなたの使用法に一致します。
リードコプシー2011

@Reedしかし、MyMethod(Action action)の代わりに(そしてActionがデリゲートである場合)、MyMethod(()=> {DoSomething();});を呼び出すことができます。BeginInvokeで同じことができないのはなぜですか?
ミカ2011

15
@Micah:実際に、デリゲートの署名がありません。これが問題の原因です。ジェネリックInvokeBeginInvoke服用しますDelegate、任意の署名のメソッドを表すことができるオブジェクトます。通常の状況(デリゲートが特定の署名に強く型付けされている場合)では、コンパイラーは特定のデリゲート型を推測できます。これが、他のシナリオでデリゲートタイプを省略して回避できる理由です。ただし、ここには実際のデリゲート型ないため、コンパイラには、デリゲート型を選択するために使用する合理的な根拠(または実際には手段さえ)がありません。
アダムロビンソン

2
@Micah:BeginInvokeはBeginInvoke(Action ..)として宣言されておらず、BeginInvoke(System.Delegate、..)として宣言されているため、これにより任意のデリゲート型を使用できますが、明示的に指定する必要があります。
リードコプシー2011

73

短い:

_dispatcher.BeginInvoke((Action)(() => DoSomething()));

8
さらに短い:式の周りに中括弧{}とセミコロンは必要ないと思います。
sp3ctum 2013年

3
()も必要ないので、そうすることができます_dispatcher.BeginInvoke((Action)(DoSomething));
mycroes 2015年

9

インラインラムダを使用しています...

Dispatcher.BeginInvoke((Action)(()=>{
  //Write Code Here
}));

7

プロジェクトからSystem.Windows.Presentation.dllを参照して追加using System.Windows.Threadingすると、ラムダ構文を使用できる拡張メソッドにアクセスできます。

using System.Windows.Threading;

...

Dispatcher.BeginInvoke(() =>
{
});

これを機能させることができません。もう少し詳しく教えていただけますか?
ティム・ポールマン2017

簡単な例を追加しました。System.Windows.Presentation.dll
logicnet.dk 2017

それはまさに私がしていることですが、今ではうまくいきます...奇妙です。前回何か間違ったことをしたのかもしれません。
ティム・ポールマン2017

3

このための拡張メソッドを作成します。例えば

public static void BeginInvoke(this Control control, Action action)
    => control.BeginInvoke(action);

これで、フォーム内から呼び出すことができますthis.BeginInvoke(() => { ... })

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.