4

他の複数のイベントがすべて発生したときに発生するイベントをサブスクライブしたいと思います。

複数のタスク ( ) を最初に行う必要があるとします (たとえば、複数の独立したビューのアニメーション化)。タスクが完了したというイベントをサブスクライブすることもでき、これらのイベントがすべて完了した後にA他の作業を実行したいと考えています ( )。B終了した。

最初のタスクの量 ( A) は毎回異なる可能性があるため、現時点ではカウンターを number of tasks に設定し、AN 個のイベントをサブスクライブし、タスク完了のイベント ハンドラーでカウンターをデクリメントし、カウンターがゼロになったら、私はタスク B を実行します。

カウンターを使用するよりも、これらのイベントを組み合わせる良い方法はありますか?

4

2 に答える 2

1

質問を正しく理解できれば、A タスクを開始するときにカウンターをインクリメントし、各タスクが完了すると、イベント ハンドラーでカウンターをデクリメントします。また、イベント ハンドラーでは、(カウンターをデクリメントした後) カウンターがゼロかどうかを確認します。その場合、タスク B を実行します。

Tasks (別名 "Task Parallel Library (TPL)" )を見ることをお勧めします。これにより、次のようなことができます。

Task.WhenAll( new Task[] {
    Task.Run(()=> { //... do work A1... },
    Task.Run(()=> { //... do work A2... },
    Task.Run(()=> { //... do work A3... }})
    .ContinueWith(()=> {//... do work B... });

更新:以下のコメントでの WPF アニメーションの言及に基づいて、Task.Runここでは適切ではない可能性があります。私の記憶が正しければ、Completedイベントを取得し、コード内でアニメーションを同期的に実行する方法がありません (「... do work A1...」のように)。

ただし、 を介してタスクを作成する代わりに、次のような拡張メソッドを介してのイベントTask.Runからタスクを作成できます。CompletedStoryboard

public static Task<Storyboard> BeginAsync(this Storyboard sb)
{
   var tcs = new TaskCompletionSource<Storyboard>();
   sb.Completed += (s, a) => tcs.TrySetResult(sb);
   sb.Begin();
   return tcs.Task;
}

このメソッドは、ストーリーボードのCompletedイベント ハンドラーで完了するタスクを作成し、タスクを返す前にストーリーボード アニメーションを開始することに注意してください。また、他のタイプやイベントについても同様の拡張メソッドを記述できることに注意してください。

たとえば、次のようにこのメソッドを使用します。

var sb1 = (Storyboard)mainWindow.FindResource("Storyboard1");
var sb2 = (Storyboard)mainWindow.FindResource("Storyboard2");
var sb3 = (Storyboard)mainWindow.FindResource("Storyboard3");

Task.WhenAll( new Task[] {
    sb1.BeginAsync(),
    sb2.BeginAsync(),
    sb3.BeginAsync() })
    .ContinueWith(() => MessageBox.Show("All done!"),
        TaskScheduler.FromCurrentSynchronizationContext());

TaskScheduler.FromCurrentSynchronizationContext()基本的に、継続タスクを UI スレッドで実行するようにスケジュールします (これは、UI 要素にアクセスする場合に必要です)。

于 2013-08-26T08:02:27.163 に答える
0

イベントごとに識別子 (たとえば、列挙型に基づく) を用意し、呼び出されると予想されるすべてのイベントをリストに追加します。イベントが実行されるたびに、リストから削除します。

各イベントで、リストが空の場合にのみ実際に動作するメソッドを呼び出します。

于 2013-08-26T08:19:42.040 に答える