无限期地运行异步方法迭代(使用嵌套迭代)

时间:2017-08-26 23:24:15

标签: c# asynchronous .net-core

我试图想出最好的方法来运行异步方法的迭代。 基本上,我在第一时间内运行了第一个TimeSpan和一个Dictionary<Item,TimeSpan>

例如:

var iteration = new TimeSpan().FromSeconds(60);

var items = new Dictionary<Item,TimeSpan>();
items.Add(item1,new TimeSpan().FromSeconds(10))
items.Add(item2,new TimeSpan().FromSeconds(30))

可以安全地假设:

    字典中
  • TimeSpan项始终为<而不是iteration
  • iteration,当转换为秒时,始终适合字典中NTimeSpan个项目(如果迭代时间为60秒,则项目的时间跨度为1或2或3或6或10或15等等。

对于每个Item我需要每X ms运行一个异步方法(由字典中的TimeSpan定义。例如:

public async Task<int> MyMethod(Item item)
{
    return await 3; // In reality something is done and a result is returned
}

这意味着对于示例中的两个项目和60秒的时间跨度,如果我从T00:00开始,我需要为MyMethod运行item1 6次(at {{ 1}},T00:00T00:10等)和T00:20 2次(item2T00:00)。

现在,这个部分相对简单,我稍微挣扎的是让T00:30在60秒内再次重复,并确保它开始是否完成了前一个。例如,如果iteration的{​​{1}}需要12秒才能完成,我仍然希望在MyMethod秒后开始另一次迭代(这意味着在某个特定时间点我会有多个执行item1 60有效。

我尝试做的事情是MyMethoditem1 void进行MyMethod调用,但无法使其发挥作用。

1 个答案:

答案 0 :(得分:1)

我自己实际上已经解决了这个问题。 Iteration是一个代表迭代的类:

public void RunIterations()
{
    var iterations = new List<Iteration>();

    // Adding items that represent the iterations to run

    // Here we're creating an array of tasks for each iteration
    // The running RunIteration for each iteration that needs to be created
    // However, the tasks will never finish unless the cancellation is requested (as we can see in RunIteration method).
    var iterationTasks = new Task[iterations.Count];

    var iterationIndex = 0;
    foreach (Iteration iteration in iterations)
    {
        iterationTasks[iterationIndex] = RunIteration(iteration);
        iterationIndex++;
    }

    Task.WaitAll(iterationTasks);
}

private async Task RunIteration(Iteration iteration)
{
        // We're creating an endless loop that will keep starting the RunAsync() for the iteration until the cancellation is requested.
        while (!_cancellationTokenSource.IsCancellationRequested)
        {
            // We're running the RunAsync() without waiting for it to finish.
            // It's done on purpose: in case any stages in the iteration take more time than expected
            // then another iteration is started in parallel as the previous one is finishing.
            iteration.RunAsync().ContinueWith(
                task => {
                    DoSomethingWithResult(task.Result);
                });

            // Waiting for the duration of the iteration to start the next one.
            await Task.Delay(( new TimeSpan().FromSeconds(60));
        }
}