首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP.MVC EF6基本填充阻塞用户界面

ASP.MVC EF6基本填充阻塞用户界面
EN

Stack Overflow用户
提问于 2016-03-24 18:26:51
回答 3查看 82关注 0票数 0

我使用的是ASP.MVC 5和EF6。我的目的是用来自另一个服务器的数据填充数据库,而不是阻塞用户界面。

数据库填充需要很多时间,大约10-15分钟。此时,用户可以使用系统进行操作。现在,他有几分钟非常严重的冰冻。因此,事实是,用户从库中加载数据并将任务加载数据一次性填充到数据库中。

我曾尝试将数据库填充代码放到另一个线程中,但没有帮助。当用户第一次登录时,他执行一些操作,开始填充数据库。执行此操作后,用户可以执行任何其他操作,并且界面不能被阻塞。

当用户使用系统时,他总是需要从我的数据库中加载一些数据。例如:当用户在1分钟内看到某个页面时,有10000个加载的数据,2分钟时有更多的数据,以此类推。

代码语言:javascript
复制
public ActionResult SomeAction()
{
    new Thread(async () =>
    {
        Thread.CurrentThread.IsBackground = true;
        await ImportTask();
    }).Start();
    ... (some code)
    return View();
}

public async Task ImportTask()
{
    for (var i = 0; i < 180; i++)
    {
        using (var context = new ApplicationDBContext())
        {
            // synchronized data download with some sided library
            var data = GetSomeDataFromAnotherServer(i); 
            foreach (var dataPart in data)
            {
                var stat = context.Data
                    .FirstOrDefault(x =>
                        x.EnumProperty == dataPart.EnumProperty &&
                        x.LongProperty == dataPart.LongProperty &&
                        x.DateTimeProperty == dataPart.DateTimeProperty)
                    ?? new DataType()
                    {
                        EnumProperty = dataPart.EnumProperty,
                        LongProperty = dataPart.LongProperty,
                        DateTimeProperty == dataPart.DateTimeProperty
                    };
                ... (some another stat filling)

                context.Statistics.AddOrUpdate(stat);
            }
            await context.SaveChangesAsync();
        }
    }
}

还有另一个问题:我有能力一次下载大约10个线程的数据。如何修改此代码才能做到这一点?

附注:代码可以在此处包含一些拼写错误

EN

回答 3

Stack Overflow用户

发布于 2016-03-24 18:47:02

不要使用Thread类,它是一个古老的神秘的,难以理解/使用的应用程序接口,已经过时了99 %的用例。虽然在asp.net中也不要使用Task.Run,但更喜欢用它来做CPU受限的工作。当你从asp中窃取线程时,asp不能很好地处理你的问题,而且很容易造成死锁。

在处理真正的异步api (如DbContext.SaveChangesAsync())时,只需使用async/await,根本不用担心线程,它们在web上下文中不会给您带来任何性能提升,甚至会损害它(还会损害可伸缩性)。

票数 0
EN

Stack Overflow用户

发布于 2016-03-24 19:49:29

尝试:

代码语言:javascript
复制
     public async Task<ActionResult> SomeAction()
    {
        await Task.Run(() => { ImportTask(); });
        return View();
    }

    public async Task ImportTask()
    {
        using (var context = new ApplicationDBContext()) 
        {
            context.Configuration.AutoDetectChangesEnabled = false;
            for (var i = 0; i < 180; i++)
            {
                var data = GetSomeDataFromAnotherServer(i);
                foreach (var dataPart in data)
                {
                    var stat = context.Data.FirstOrDefault(x => x.EnumProperty == dataPart.EnumProperty && x.LongProperty == dataPart.LongProperty && x.DateTimeProperty == dataPart.DateTimeProperty) 
                        ?? new DataType()
                                                                                                                                                                                                              {
                    ...
                    (some
                    another stat 
                    filling)

                    context.Statistics.AddOrUpdate(stat);
                }
            }
            await context.SaveChangesAsync();
        }
    }

for (var i = 0; i < 180; i++)中使用using (var context = new ApplicationDBContext())会导致180次DbContext的创建和处置操作。此外,对于批量插入,为了提高速度,您可以使用context.Configuration.AutoDetectChangesEnabled = false;或尝试这个库https://efbulkinsert.codeplex.com/

票数 0
EN

Stack Overflow用户

发布于 2016-03-24 22:01:10

您不需要在ASP.NET上下文中通过task.Run()创建原始线程或展开任务,因为这在ASP.NET上下文中主要是性能障碍。我也不会将其用于“一发即忘”的实现,因为它非常不可靠。如果你想着火,但忘记了,你可以考虑使用:HostingEnvironment.QueueBackgroundWorkItem,但我也不确定这是不是最好的方法。

您是否考虑过创建另一个进程来执行此操作,而不是在web请求过程中执行此操作?也许在服务器上运行的服务可以监视某人何时登录并执行数据移动?另一种选择可能是你从浏览器上的某个javascript调用这个数据移动操作来启动它?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36197959

复制
相关文章

相似问题

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