最近WPF関連の記事はバグ報告がメインになってしまって、寂しい限りです。いやWPF好きなんですけど。
前置きはそれぐらいにしてと、WPFに限らずですがイベントドリブンで複数のイベントに連動させて一つ処理を行う場合、一度実行すればよい処理を複数回実行してしまうことが少なからずあります。
といっても、言葉で説明しても難しいのでSampleを貼っておきます。 コードで語る(?)
https://skydrive.live.com/embedicon.aspx/.Public/AsyncOnce.zip?cid=a46d108f79f66d2b&sc=documents
実行画面がこちら。

よくある(?)、足算アプリです。主な機能は2つ。
・左側もしくは右側のテキストボックスに数字を入れると、合計値が計算されます。
・Resetボタンをクリックすると両側のテキストが0に初期化されます。結果、合計値も0になります。
で、主なコードは以下の通りです。
/// <summary>
/// +の左の値
/// </summary>
public int Left
{
get { return left; }
set
{
if (left == value) return;
left = value;
// 計算
Calc();
OnPropertyChanged("Left");
}
}
/// <summary>
/// +の右の値
/// </summary>
public int Right
{
get { return right; }
set
{
if (right == value) return;
right = value;
// 計算
Calc();
OnPropertyChanged("Right");
}
}
/// <summary>
/// 計算結果
/// </summary>
public int Answer
{
get { return answer; }
set
{
if (answer == value) return;
answer = value;
OnPropertyChanged("Answer");
}
}
/// <summary>
/// リセットコマンドで実行されるメソッド
/// </summary>
/// <param name="obj"></param>
public void Reset(object obj)
{
// 両方の値をリセット
this.Left = 0;
this.Right = 0;
}
/// <summary>
/// 計算ロジック
/// </summary>
private void Calc()
{
// 同期的に計算すると複数回実行されてしまう。
Answer = left + right;
}
左右それぞれのテキストボックスに対応する値が更新された場合にCalc()メソッドが呼び出されます。そのため、Reset()メソッド実行時には左右それぞれのプロパティーが更新されるため、Calc()が2回呼び出されることになります。
今回は、単なる足算なので、2度計算してもたいしたことはないんですが、重たい処理だったりすると複数回実行することはためらわれます。
そんな場合は、計算ロジックを以下のように変更することによって、Dispatcherを利用し非同期的に1度だけの呼び出しを実現します。
/// <summary>
/// 非同期実行が予約されているかを判定するフラグ
/// </summary>
private bool queueFlag = false;
/// <summary>
/// 非同期に計算するロジック
/// </summary>
private void Calc()
{
if (queueFlag) return;
queueFlag = true;
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
queueFlag = false;
Answer = Left + Right;
}), null);
}