gpt4 book ai didi

.net - 并行化具有不同边界的多个相关操作

转载 作者:行者123 更新时间:2023-12-01 05:25:44 26 4
gpt4 key购买 nike

这是我需要完成的任务列表:

  1. 读取文件的一大块(磁盘 IO 限制)
  2. 加密所述 block (CPU 限制)
  3. 上传所述 block (网络 IO 限制)
  4. 重复此操作直至文件上传

问题在于如何以最高的效率和性能来实现这一目标。

我尝试使用 Parallel.For 来封装整个操作 block ,但我认为这不是解决这个问题的最佳方法,因为每个操作都有不同的特征,可以被考虑在内(正如我在上面的列表中指出的那样)。

读完这篇文章后TPL article this question中建议,在回顾了该问题的实证数据后,我认为 TPL 是我想要走的路。但我应该如何打破这个问题以获得最大的效率和性能呢?考虑到上传可能是整个操作的瓶颈,我是否应该尝试对前两个操作进行多线程处理?

感谢您的投入。

编辑:

我尝试使用任务和继续让操作系统处理它,但我认为我遇到了另一堵墙 - 当我等待所有上传任务完成时,垃圾收集器似乎没有工作没有清理我读入上传的数据,因此我最终耗尽了内存。还有一个需要考虑的问题。

最佳答案

如果你不能使用.Net 4.5,我建议你使用一个线程读取磁盘,一个线程用于加密,一个线程用于上传。为了在它们之间进行通信,您可以使用 BlockingCollection<byte[]> 形式的生产者-消费者模式。每对线程(1-2 和 2-3)之间。

但是由于您可以使用 .Net 4.5,因此您可以使用 TPL Dataflow,它非常适合此任务。使用 TPL 数据流意味着您不会浪费线程来读取和上传(尽管这对您来说很可能并不重要)。更重要的是,这意味着您可以轻松地并行加密每个 block (假设您可以做到这一点)。

您要做的就是拥有一个用于加密的 block 、一个用于上传的 block 和一个用于从文件读取的异步任务(实际上,它不必是完整的 Task )。用于加密的 block 可以配置为并行执行,并且两个 block 都应该配置一些最大容量(否则,限制将无法正常工作,并且整个文件将被尽快读取,这可能导致 OutOfMemoryException)。

在代码中:

var uploadBlock = new ActionBlock<byte[]>(
data => uploadStream.WriteAsync(data, 0, data.Length),
new ExecutionDataflowBlockOptions { BoundedCapacity = capacity });

var encryptBlock = new TransformBlock<byte[], byte[]>(
data => Encrypt(data),
new ExecutionDataflowBlockOptions
{
BoundedCapacity = capacity,
MaxDegreeOfParallelism = degreeOfParallelism
});

encryptBlock.LinkTo(
uploadBlock,
new DataflowLinkOptions { PropagateCompletion = true });

while (true)
{
byte[] chunk = new byte[chunkSize];
int read = await fileStream.ReadAsync(chunk, 0, chunk.Length);
if (read == 0)
break;
await encryptBlock.SendAsync(chunk);
}

fileStream.Close();
encryptBlock.Complete();
await uploadBlock.Completion;
uploadStream.Close();

关于.net - 并行化具有不同边界的多个相关操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13963134/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com