如果您不能使用.Net 4.5,我建议您使用一个线程从磁盘读取,一个线程用于加密,一个线程用于上传。BlockingCollection<byte[]>
为了在它们之间进行通信,您可以在每对线程(1-2 和 2-3)之间使用生产者-消费者模式。
但是由于您可以使用 .Net 4.5,因此您可以使用 TPL Dataflow,它非常适合这项任务。使用 TPL 数据流意味着您不会浪费线程来读取和上传(尽管这对您来说很可能并不重要)。更重要的是,这意味着您可以轻松地并行加密每个块(假设您可以这样做)。
你要做的是有一个块用于加密,一个块用于上传和一个异步任务(实际上,它不必是一个完整的Task
)用于从文件中读取。可以将用于加密的块配置为并行执行,并且两个块都应配置为具有最大容量(否则,节流将无法正常工作,并且将尽可能快地读取整个文件,这可能导致 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();