使同步数据库操作异步

Posted

技术标签:

【中文标题】使同步数据库操作异步【英文标题】:Make Synchronous database operation asynchronous 【发布时间】:2021-11-28 07:37:32 【问题描述】:

我想在 Asp.Net MVC 4.5.2 应用程序中使用批量数据库操作。 有很好的库Z.EntityFramework.Extensions,但要 800 美元。 还有免费的 lib EF.BulkExtensions,但它不包含异步方法。 问题:如果我会这样做

await Task.Run(() => 
 
    MyDatabaseContext.BulkUpdate(entities); 
);

它会像我使用异步方法一样工作吗(就使用 IIS 的线程池而言)?

【问题讨论】:

EF.BulkExtensions 确实有一个BulkUpdateAsync。但实际上没有bulk updatedelete,只有BULK INSERT(即以最少的日志记录插入大量数据)。所有谈论“批量更新”的库实际上都会在后台生成一个 SQL 命令,该命令通常将数据作为表值类型或 MERGE 命令的一部分发送。 @PanagiotisKanavos 不,它没有异步功能。我将 EF.BulkExtensions.1.4.2 与 .netframework 4.5.2 一起使用。您的链接指向 EFCore 库。我会尝试升级框架版本。 EFCore 与网络框架 4.6+ 和 EF.Core 3+ 兼容。但是我依赖于EntityFramework.extenDED,它依赖于简单的实体框架 那就不要使用那个方法了。没有像BULK INSERT 那样运行的 BULK UPDATE 命令,即使用最少的日志记录以尽可能最快的方式插入数据。每个声称“批量更新”的库所做的是生成一个普通旧的、完全记录的UPDATE 命令,该命令以某种方式与新数据结合,无论是表值参数的形式还是VALUES 中的数据条款。这些选项都不能很好地利用索引,从而导致性能欠佳,并且不能扩展到大量行 如果您使用SqlBulkCopy 将行插入到临时表中,然后对与临时表连接的目标(即UPDATE target SET .... FROM target inner join staging on staging.ID=target.ID)执行更新,会快很多。 【参考方案1】:

你至少应该这样做:

var task = new Task(() =>  MyDatabaseContext.BulkUpdate(entities) , TaskCreationOptions.LongRunning);
await task;

这可确保您的任务在其自己的线程中运行,并且不会占用任务池中的任务。

【讨论】:

以上是关于使同步数据库操作异步的主要内容,如果未能解决你的问题,请参考以下文章

架构笔记[一]:同步与异步

第十次总结 线程的异步和同步

执行同步和异步操作

java异步方法啥意思

实现异步转同步的几种方式

python网络编程基础(线程与进程并行与并发同步与异步)