web-dev-qa-db-ja.com

ディスパッチャーのBeginInvoke構文

私はいくつかのWCF Data Servicesの例に従っていましたが、次のコードがあります。

private void OnSaveCompleted(IAsyncResult result)
    {
        Dispatcher.BeginInvoke(() =>
        {
            context.EndSaveChanges(result);
        });
    }

以下によって呼び出されます:

this.context.BeginSaveChanges(SaveChangesOptions.Batch, this.OnSaveCompleted, null);

ここで少し混乱しています。まず、コードの最初のビットは、「引数型ラムダ式がパラメーター型System.Delegateに割り当てられない」という構文エラーを示しています。だから私は盲目的にサンプルコードを追おうとする代わりに、ここで何が起こっているのかを理解しようとしました。残念ながら、エラーと実際に何が起こっているのかを理解するのに苦労しています。

これは簡単だと確信しているので、少しばかげていると感じます。

啓発に感謝します!

43
Jon Archway

問題は、ラムダ式をどの種類のデリゲートに変換しようとしているかをコンパイラが認識していないことです。これは、キャストまたは別の変数で修正できます。

private void OnSaveCompleted(IAsyncResult result)
{        
    Dispatcher.BeginInvoke((Action) (() =>
    {
        context.EndSaveChanges(result);
    }));
}

または

private void OnSaveCompleted(IAsyncResult result)
{
    Action action = () =>
    {
        context.EndSaveChanges(result);
    };
    Dispatcher.BeginInvoke(action);
}
95
Jon Skeet

Jon Skeetによる回答は非常に良いですが、他の可能性もあります。読みやすく覚えやすい「新しいアクションを開始する」ことを好みます。

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(() =>
    {
        context.EndSaveChanges(result);
    }));
}

または

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(delegate
    {
        context.EndSaveChanges(result);
    }));
}

または

private void OnSaveCompleted(IAsyncResult result)
{       
    Dispatcher.BeginInvoke(new Action(() => context.EndSaveChanges(result)));
}
11
CoperNick

メソッドがパラメーターを必要としない場合、これは私が見つけた最短バージョンです:

Application.Current.Dispatcher.BeginInvoke((Action)MethodName); 
3
Alon Amsalem