2017-08-28 4 views
0

私は、コードの一部がタイマーの遅れでループ内で実行されるアプリケーションを持っています。私は宣言したアプリケーションの開始時にwhileループで実行される実行中のタイマーを停止するにはどうすればよいですか?

public static CancellationTokenSource tokenSource1 = new CancellationTokenSource(); 
public static bool Timer1Running; 

はここでループエリアです:

while (App.runCardTimer && App.TimerSeconds > 0) 
{ 
    App.Timer1Running = true;  
    … 
    await Task.Delay(1000, App.tokenSource1.Token); 
    App.TimerSeconds--;  
    App.Timer1Running = false;  
} 

私のアプリケーションは、このように画面上のクリックに応答します。

wordGrid.GestureRecognizers.Add(  
    new TapGestureRecognizer()  
    {   
     Command = new Command(() =>   
     {   
     App.TimerSeconds = 0;   
     if (App.tokenSource1 != null && App.Timer1Running)   
     {    
      App.tokenSource1.Cancel();   
     }  
     })  
    }); 

実行時に画面がクリックされると、コードに移動します0 App.tokenSource1.Cancel()

しかし、それはその後停止するようです。

誰かが私が間違っていると思われるアイデアはありますか?私はすぐにコードApp.TimerSeconds--;に行くと予想していただけで、それが前に停止することを期待していなかった。

+1

しかし、あなたがApp.TimerSeconds = 0設定されていないので、それはApp.TimerSeconds> 0に依存しているので、きっとしばらくは今、もはや、実行していますか? –

+0

'await Task.Delay'はキャンセル時にTaskCanceledExceptionをスローします –

+0

タイマーが必要な場合は、タイマーを使用します。 [ソースコードをチェックする](https://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,5896)、あなたは 'Task.Delay'自体がタイマーを使ってTaskCompletionSourceの完了ステータスを設定します。 –

答えて

1

await Task.Delay(1000, App.tokenSource1.Token);
スローSystem.Threading.Tasks.TaskCanceledExceptionキャンセルすると。
だから、のtry-catchでラップする必要があります。

{ 
    App.Timer1Running = true;  
    … 
    try 
    { 
     await Task.Delay(1000, App.tokenSource1.Token); 
    } 
    catch(TaskCanceledException ex){} 
    App.TimerSeconds--;  
    App.Timer1Running = false;  
} 
+0

ありがとうございます。ところで。新しいtokenSource1を作成したら、それを何度も何度も使うことができますか? – Alan2

+0

トークンを複数回取得して、多くの操作でそれらを消費することができます。しかし、CancellationTokenSourceが取り消されると、それから取得するすべてのトークンもキャンセルされ、CancellationTokenSource自体がキャンセル状態に永続的に移行します。 –

関連する問題