首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ABP框架/并行编程

ABP框架/并行编程
EN

Stack Overflow用户
提问于 2022-02-25 05:55:13
回答 1查看 188关注 0票数 0

我有一个AsyncPeriodicBackgroundWorkerBase基类(DataValidateWorker),它每隔1分钟运行一次。

我需要将从db获得的数据发送到第三方web服务,并更新数据库中的结果。Web服务响应大约在30-40秒内到达。因此,我需要同时发送服务查询,而不是顺序发送

因此,我按照下面所示的并行编程编写了代码。我无法为我编写的任务提取数据库连接。DB连接关闭后,我遇到了许多错误,比如执行。如何为任务创建db连接?

与ABP相比,在外部应用程序(exe或service)中编写此作业会更好吗?

代码语言:javascript
复制
public class DataValidateWorker : AsyncPeriodicBackgroundWorkerBase
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IDataFilter _dataFilter;

public DataValidateWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory, IDataFilter dataFilter, IUnitOfWorkManager unitOfWorkManager) : base(timer, serviceScopeFactory)
{
    _dataFilter = dataFilter;
    _unitOfWorkManager = unitOfWorkManager;
    Timer.Period = 60 * 1000; // 60 seconds
}

[UnitOfWork]
protected async override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
    try
    {
        var notificationValidationRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<NotificationValidation, int>>();
        var notificationValidationItems = await notificationValidationRepository.GetQueryableAsync();
        List<NotificationValidation> list = new List<NotificationValidation>();
        using (var uow = _unitOfWorkManager.Begin())
        {
            using (_dataFilter.Disable<IMultiTenant>())
            {
                list = notificationValidationItems.Where(x => x.RecordDateTime <= DateTime.Now && x.ValidationResult == (int)ValidationResult.NotStarted).ToList();
            }
        }
        NotificationValidationArgs jobArgs = new NotificationValidationArgs();
        foreach (var item in list)
        {
            jobArgs.notificationValidationId = item.Id;
            Task taskA = Task.Factory.StartNew(async (Object obj) =>
            {
                // doing some third party web service operations and db operations
            }, jobArgs);
        }
    }
    catch (Exception ex)
    {
        Logger.LogCritical(2001, ex, DateTime.Now.ToString() + " -> DataValidateWorker -> try 1 -> RDMS uow");
    }
}
}
EN

回答 1

Stack Overflow用户

发布于 2022-03-01 12:51:44

您不需要等待任何任务,因此对象的生存期将在任务仍在运行时结束。

尝试将所有任务存储在集合中,并在方法执行完成之前等待它们。

如下所示:

代码语言:javascript
复制
public class DataValidateWorker : AsyncPeriodicBackgroundWorkerBase
{
    public DataValidateWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory) : base(timer, serviceScopeFactory)
    {
    }

    protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
    {
        var tasks = new List<Task>();
        foreach (var item in list)
        {
            tasks.Add(YourLongJob(arg)); // don't await here. collect in a collection
        }

        await Task.WhenAll(tasks); // wait until all of them is completed.
    }

    private async Task YourLongJob(object arg)
    {
        await Task.Delay(30 * 1000); // a long job
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71261634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档