当前位置:  开发笔记 > 编程语言 > 正文

MVC5网站中的批处理

如何解决《MVC5网站中的批处理》经验,为你挑选了1个好方法。

我有一个使用EF进行数据访问的MVC网站。该应用程序接收数据,运行一系列计算并存储结果。每一批数据可以有数千条记录,并且计算平均需要30秒-我想在后台运行所有这些。

到目前为止,我已经安装了Hangfire来触发批次。然后,我做:

var queue = new Queue();

// queue is populated ...

while (queue.Any())
{
    var item = queue.Dequeue();
    var task = Task.Run(() =>
    {
        using (var context = new MyDbContext())
        {
            context.MyItem.Add(item);

            // Run Calculations

           try {
               context.SaveChanges();
           }
           catch {
               // Log error
           }
        }
    }
}

批处理正在运行时,网站要么变得完全无响应,要么收到“底层提供程序在打开时失败”错误。

有更好的方法吗?



1> i3arnon..:

似乎您正在使用Task.Run而不是等待任务完成来创建任务。这意味着您将为队列中的每个项目生成一个任务,这些任务将同时在不同ThreadPool线程上运行。这可能是一个很大的负担,可能会(并且确实会)影响您的常规请求。

您应该以某种方式限制这些任务的并发性。最简单的IMO是使用TPL Dataflow的ActionBlock。您使用委托和选项(例如MaxDegreeOfParallelism)创建块,将项目发布到其中并等待其完成:

block = new ActionBlock(item =>
{
    using (var context = new MyDbContext())
    {
        context.MyItem.Add(item);

        // Run Calculations

       try {
           context.SaveChanges();
       }
       catch {
           // Log error
       }
    } 
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 });

while (queue.Any())
{
    var item = queue.Dequeue();
    block.Post(item);
}

block.Complete();
await block.Completion;

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有