2017-01-05 13 views
0

ここで非同期初心者は、このスキルを向上させようとしています。Task.WhenAllなどを使用して最小時間間隔の後にループ内でメソッドを実行

メソッドを最大で毎に500ミリ秒ごとに実行したい、または指定された実行にそれより時間がかかる場合は、それを長くします。この場合、ループは即座に継続することができます。

私はStopWatchまたは他のタイマーでそれを行うことができることを知っていますが、私はasync/awaitでこれをやりたいと思います。

私はクイックスパイクを開発しましたが、実行すると非常にしっかりと実行されているように見えます。 "待っている"ことを忘れるのは何ですか?

class Program 
{ 
    static void Main(string[] args) 
    { 
     while (true) 
     { 
      Run(); 
     } 
    } 

    static async void Run() 
    { 
     var task1 = Task.Delay(500); 
     var task2 = DoSomethingAsync(); 

     await Task.WhenAll(task1, task2); 
    } 

    static async Task DoSomethingAsync() 
    { 
     Random r = new Random(); 
     int miliseconds = Convert.ToInt32(r.NextDouble() * 1000); 
     await Task.Delay(miliseconds); 
     Console.WriteLine(miliseconds); 
    } 
} 
+1

Run();をRun()。Wait()に変更します。 Sidenote: '.Wait()'や '.Result'をブロックするのを避けますが、このデモのためには行います。 –

+0

@PeterBons私は 'Task.WhenAll(...)。GetAwaiter()。GetResult()'を使って作業しましたが、なぜ他の方法がうまくいかなかったのか、なぜあなたの提案を避けるべきなのか理解できませんでした答え、そして私が生産の代わりに使うべきもの... – heltonbiker

+0

@LB私は同時に複数の呼び出しを実行しないことを保証する必要があります。つまり、メソッドが_after_前回の呼び出しが完了したことを確認する必要があります。 。 'Timer'はそれを考慮に入れますか? – heltonbiker

答えて

3

あなたはトップレベルのタスク(あなたが持っていないので)を待っていません。

class Program 
{ 
    static void Main(string[] args) 
    { 
     while (true) 
     { 
      Run().Wait(); // Wait on each iteration. 
     } 
    } 

    // Need to return Task to be able to await it. 
    static async Task Run() 
    { 
     var task1 = Task.Delay(500); 
     var task2 = DoSomethingAsync(); 

     await Task.WhenAll(task1, task2); 
    } 

    static async Task DoSomethingAsync() 
    { 
     Random r = new Random(); 
     int miliseconds = Convert.ToInt32(r.NextDouble() * 1000); 
     await Task.Delay(miliseconds); 
     Console.WriteLine(miliseconds); 
    } 
} 

さて、キャッチは.Wait()を使用してあります:それはブロックの実行がこれを試してみてください。詳細については、この優れたガイド:https://msdn.microsoft.com/en-us/magazine/jj991977.aspxを参照してください。しかし、コンソールアプリケーションのMainメソッドのために、それは完全に安全です、心配しないでください。

async void MyTask() { ... }ではなく、常にTaskを返すようにしてください。あなたの場合、Run()メソッドが完了するのを待つのを防ぎます。

関連する問題