使用Task.WhenAll或类似方法在最小时间间隔后在循环中执行方法

时间:2017-01-05 20:48:06

标签: c# asynchronous async-await task-parallel-library

异步初学者,试图提高这项技能。

我想每500毫秒执行一次方法,如果给定的执行时间超过这个时间,则需要更长时间。在这种情况下,循环可以立即继续。

我知道我可以用StopWatch或其他一些计时器来做到这一点,但我想用async / await构造来做到这一点。

我开发了一个快速尖峰,但是当我运行它时,它似乎执行非常紧密,而不是一次500毫秒或更长时间。我打算做什么,等待"?

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 个答案:

答案 0 :(得分: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。但不要担心,对于Console App的Main方法,它是完全安全的。

同一指南还解释了为什么您应该始终尝试返回Task而不是async void MyTask() { ... }。在您的情况下,它会阻止您等待Run()方法完成。