【发布时间】:2017-10-12 04:14:27
【问题描述】:
是否有一种 TPL 语法允许您将对象从池中注入到任务中,这样一个对象一次只能由一个线程使用?甚至更好 - 仅由同一个线程使用?
使用示例
假设我想创建 10 个线程来打开 10 个文件:1.txt、2.txt、3.txt ... 10.txt 并将 500 000 个结果数字随机写入这些文件。
我可以这样做:
ConcurrentQueue<int> objs = new ConcurrentQueue<int>(); // 500000 numbers go here
Task[] tasks = Enumerable.Range(1, 10)
.Select(i =>
{
return Task.Factory.StartNew(() =>
{
using (var f = File.Open($"{i}.txt"))
{
using (var wr = StreamWriter(f))
{
while (objs.TryDequeue(out int obj))
{
wr.WriteLine(obj);
}
}
}
}
})
.ToArray();
Task.WaitAll(tasks);
但是,是否可以在不使用并发集合的情况下仅使用 TPL 提供相同的行为?
【问题讨论】:
-
你知道ThreadLocal
吗? -
为什么不调整
ForEach和ParallelOptions?Parallel.ForEach(objs, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, o => {...});另一种可能是Parallel Linq:objs.AsParallel().WithDegreeOfParallelism(4).ForAll(o = > ...); -
这听起来像XY Problem。您有一个数据库性能问题 X,并认为您将通过并行执行大量连接 (Y) 来解决它。当失败时,您会询问 Y。并行执行多个数据库查询不会解决任何性能问题。不过,这很容易使它们变得更糟。 ORM不用于处理大量数据。
-
最后,ORM既不是报告工具也不是批量导入工具。它们可以处理单个对象图,但不能处理多行。您的实际问题是什么?
-
BTW ORM 不提供抽象或设计优势。当您导入数据时,没有实体,也没有行为。 实际实体是源、行、字段、数据、转换。在将它们存储到目的地之前,您会处理一个 流 行,这些行会在运行中进行转换。您可以使用几 MB 的 RAM 以这种方式处理数百万行。尝试使用 ORM
标签: c# multithreading nhibernate task-parallel-library