使用 For 循环进行异步和等待 [英] Async and Await with For Loop

查看:48
本文介绍了使用 For 循环进行异步和等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Windows 服务,可以根据计划运行各种作业.在确定要运行哪些作业后,一个调度对象列表被发送到一个方法,该方法遍历列表并运行每个作业.问题在于,由于外部数据库调用,某些作业可能需要长达 10 分钟才能运行.

I have a Windows Service that runs various jobs based on a schedule. After determining which jobs to run, a list of schedule objects is sent to a method that iterates through list and runs each job. The problem is that some jobs can take up to 10 minutes to run because of external database calls.

我的目标是不让一项作业在队列中阻塞其他作业,基本上一次运行不止一项.我认为使用 async 和 await 可以解决这个问题,但我以前从未使用过这些.

My goal is to not have one job block others in queue, basically have more than one run at a time. I thought that using async and await could be to solve this, but I've never used these before.

当前代码:

public static bool Load(List<Schedule> scheduleList)
{
    foreach (Schedule schedule in scheduleList)
    {
        Load(schedule.ScheduleId);
    }

    return true;
}

public static bool Load(int scheduleId)
{
    // make database and other external resource calls 
    // some jobs run for up to 10 minutes   

    return true;
}

我尝试更新到此代码:

public async static Task<bool> LoadAsync(List<Schedule> scheduleList)
{
    foreach (Schedule schedule in scheduleList)
    {
        bool result = await LoadAsync((int)schedule.JobId, schedule.ScheduleId);
    }

    return true;
}

public async static Task<bool> LoadAsync(int scheduleId)
{
    // make database and other external resource calls 
    // some jobs run for up to 10 minutes   

    return true;
}

问题是第一个 LoadAsync 在将控制权交还给循环之前等待作业完成,而不是允许所有作业开始.

The issue is that the first LoadAsync waits for the job to finish before giving control back to the loop instead of allowing all the jobs to start.

我有两个问题:

  1. 高级 - aysnc/await 是最佳选择,还是应该使用不同的方法?
  2. 需要更新什么才能让循环在不阻塞的情况下启动所有作业,但在所有作业完成之前不允许函数返回?

推荐答案

高级 - 异步/等待是最佳选择,还是应该使用不同的方法?

High Level - Are async/await the best choice, or should I use a different approach?

async-await 非常适合您尝试执行的操作,即同时卸载多个 IO 绑定任务.

async-await is perfect for what you're attempting to do, which is concurrently offloading multiple IO bound tasks.

需要更新什么才能让循环在不阻塞的情况下启动所有作业,但不允许函数在所有作业完成之前返回?

What needs to be updated to allow the loop to kick off all the jobs without blocking, but not allow the function to return until all jobs are completed?

您的循环当前正在等待,因为您await 每次调用LoadAsync.你想要的是同时执行它们,而不是使用 Task.WhenAll 等待它们全部完成:

Your loop currently waits because you await each call to LoadAsync. What you want is to execute them all concurrently, than wait for all of them to finish using Task.WhenAll:

public async static Task<bool> LoadAsync(List<Schedule> scheduleList)
{
   var scheduleTaskList = scheduleList.Select(schedule => 
                          LoadAsync((int)schedule.JobId, schedule.ScheduleId)).ToList();
   await Task.WhenAll(scheduleTaskList);

   return true;
}

这篇关于使用 For 循环进行异步和等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆