Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ASP.NET异步/等待进行线程管理_C#_Multithreading_Entity Framework_Asynchronous_Async Await - Fatal编程技术网

C# 使用ASP.NET异步/等待进行线程管理

C# 使用ASP.NET异步/等待进行线程管理,c#,multithreading,entity-framework,asynchronous,async-await,C#,Multithreading,Entity Framework,Asynchronous,Async Await,我有一个数据库实体类型entity,一长串东西和方法 private Task<Entity> MakeEntity(Thingy thingy) { ... } 私有任务生成实体(Thingy Thingy){ ... } MakeEntity做很多事情,并且是CPU限制的。我想将我所有的东西转换成实体,并将它们保存在db.context中。考虑到 我不想尽快完成 实体的数量很大,我想有效地使用数据库,所以我想开始保存更改并等待远程数据库完成它的工作 我如何才能做到这一

我有一个数据库实体类型
entity
,一长串
东西和方法

private Task<Entity> MakeEntity(Thingy thingy) {
  ...
}
私有任务生成实体(Thingy Thingy){
...
}
MakeEntity做很多事情,并且是CPU限制的。我想将我所有的东西转换成实体,并将它们保存在db.context中。考虑到

  • 我不想尽快完成
  • 实体的数量很大,我想有效地使用数据库,所以我想开始保存更改并等待远程数据库完成它的工作

我如何才能做到这一点?我真正想要的是在等待数据库完成它的工作时循环,并提供到目前为止所有新创建的实体,直到数据库处理完它们为止。去那里最好的路线是什么?如果同时调用,我会遇到saveChanges,所以我不能这样做。我真正想要的是有一个由八个线程组成的线程池(或者更确切地说,有多少个线程就有多少个线程)来执行CPU绑定的工作,一个线程执行
SaveChanges()

您可以设置一个由N个CPU工作线程组成的管道,将其送入数据库工作线程。数据库工作人员可以对项目进行批处理

由于
MakeEntity
受CPU限制,因此不需要在那里使用
async
wait
<代码>等待
不会创建任务或线程(一种常见的误解)

您需要提供一个从
IEnumerable
创建批的方法。这可以在网上找到

如果数据库部分不需要批处理,可以删除该代码

对于数据库部分,可能是因为它似乎是一个低频操作。

这是一种“异步流”,这总是有点尴尬

在这种情况下(假设您确实希望在ASP.NET上使用多线程,一般不推荐使用多线程),我认为这是您最好的选择。您可以将
TransformBlock
与一起使用,并将其链接到执行
SaveChanges
操作的
ActionBlock


请记住,对CPU绑定的代码使用同步签名(而不是
async
/
await
),对I/O绑定的代码使用异步方法(即
savechangesync
)。

您确定要在ASP.NET上使用多线程吗?请记住,当单个请求使用多个线程时,这将显著影响您的可伸缩性,因为这些线程不能用于其他请求。您是否对每个
Thingy
实例重复调用
MakeEntity
?此外,是否无法批处理一堆
Thingy
的CPU限制处理,并将生成的
实体
附加到上下文中,然后只为一个DB往返调用
SaveChanges
?@Asad MakeEntity应该为每件事情调用,是吗(但这实际上是我问题的一部分。为整个批次调用一次SaveChanges将是最好的,但由于所需的工作量不可行。我要避免的主要事情是独立工作
MakeEntity
,并等待
SaveChanges
的中间结果,同时注意由于EF不支持多个“正在运行”的SaveChanges。
var thingies = ...;
var entities = thingies.AsParallel().WithDOP(8).Select(MakeEntity);
var batches = CreateBatches(entities, batchSize: 100);

foreach (var batch in batches) {
 Insert(batch);
}