2017-10-29 1 views
3

ラベルとボタンがあるとします。ボタンをクリックすると、ラベルに何らかのテキスト(「hello、world!」など)が設定され、5秒後に消えます。十分に簡単ですね。ラベルの内容を設定して5秒後に消えるようにする

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
{ 
    Label = "hello, world!"; 
    await Task.Delay(5_000); 
    Label = string.Empty; 
} 

今度は、私はボタンが後続の各ボタンのクリックに応答残るべき追加の要件を持っているとしましょう、と今でラベルテキストがラベルのテキスト、つまり次の5秒間hello, world!ままにしてください:私は、次の実装を持っていますボタンが最後にクリックされてから5秒間続けなければなりません。前のコードの問題点は、2.5秒前にボタンをクリックしてもう一度クリックすると、ラベルテキストが2.5秒後に消えてしまうことです。これを解決する私の考えは、タスクのリストを維持し、遅延タスクを追加し、ラベルをクリアする前にタスクリストを待つことでした。これは実装です:

private static readonly List<Task> TaskList = new List<Task>(); 
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
{ 
    Label = "hello, world!"; 
    TaskList.Add(Task.Delay(5_000));  
    await Task.WhenAll(TaskList); 
    if (TaskList.TrueForAll(t => t.IsCompleted)) 
    { 
    TaskList.RemoveAll(t => t.IsCompleted); 
    Label = string.Empty; 
    } 
} 

は、私の知る限りでは、この実装は動作しますが、私はそれが動作絶対に確認する方法がわからないので、私は、非同期プログラミングについて多くを知りません。

質問
これはどのように実装しますか?これを実装するより良い方法はありますか?私はもともとTask.WhenAll()がすべてのタスクが完了するのを待つことに気付いたと考えましたが、これは当てはまりません。私は何が間違っていますか?

編集:キャンセルトークンを使用して 実装:

private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); 
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
{ 
    Label = "hello, world!"; 
    _cancellationTokenSource.Cancel(); 
    _cancellationTokenSource = new CancellationTokenSource(); 
    try 
    { 
    await Task.Delay(5_000, _cancellationTokenSource.Token); 
    Label = string.Empty; 
    } catch (TaskCanceledException) { } 
} 
+0

あなたが探している用語は、ボタンクリックのイベントハンドラを調整する方法ですと信じています – Nkosi

+0

@Nkosiもう少し言えますか? – asfeynman

答えて

3

だけCancellationTokenを使用して、保留中のタスクawait Task.Delay(5_000, cancelToken);をキャンセルし、すぐに新しいものを開始します。

+0

取り消しトークンを使用して実装を追加しましたが、コメントできますか?ありがとう。 – asfeynman

+0

@asfeynmanあなたのコードは一般的によく見えますが、 '_cancellationTokenSource'は静的であってはいけません。 – Kostya

+0

偉大な、私はそれを修正します。 – asfeynman

関連する問題