你如何实现异步I / O?

时间:2015-01-29 20:10:32

标签: c# multithreading encryption asynchronous

我正在编写一个加密文件的程序,这意味着我需要读取大量数据,加密数据并将数据写入新文件。为了提高性能,我试图多线程化这个过程。我创建了两个阻塞集合,使用它们作为队列我将数据读入一个字节数组并将该数组传递到第一个阻塞集合中,我将该数组从阻塞集合中取出,加密并将其传递给第二个阻塞集合我取出那个数组并将其写入文件。

虽然我的速度有所提高,但这个过程非常不可靠。它可以从30 / mb开始,以35mb / s的峰值开始,并且在处理了大约800Mb之后大幅下降至几乎静止。我有一种强烈的感觉,我做错了,我今天下午花了三个小时的最好时间,甚至更长的昨天试图了解我如何能够异步使用filestream.beginread()来提高可靠性和速度。 / p>

以下是代码:

   public void Encrypt()
    {

        using (BlockingCollection<Byte[]> EncryptionQueue = new BlockingCollection<Byte[]>(32),
                                          WritingQueue = new BlockingCollection<Byte[]>(32))
        {
            Task readAction = Task.Factory.StartNew(() =>
            {
                FileStream input = new FileStream(DataFile.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 8);
                BinaryReader binaryInput = new BinaryReader(input);
                ByteTotal = (int)input.Length;
                while (BytesLeft < ByteTotal)
                {
                    EncryptionQueue.Add(binaryInput.ReadBytes(8192));
                    BytesLeft += 8192;
                }
                EncryptionQueue.CompleteAdding();
                input.Close();
            }, TaskCreationOptions.LongRunning);


            Task encryptAction = Task.Factory.StartNew(() =>
            {
                RC4Engine StreamCipher = new RC4Engine(this.keyString);
                foreach (Byte[] chunk in EncryptionQueue.GetConsumingEnumerable())
                {
                    int len = chunk.Length;
                    for (int x = 0; x < len; x++)
                    {
                        chunk[x] ^= StreamCipher.OutputByte();
                    }
                    WritingQueue.Add(chunk);
                }
                WritingQueue.CompleteAdding();
            }, TaskCreationOptions.LongRunning);


            Task writeAction = Task.Factory.StartNew(() =>
            {
                FileStream output = new FileStream(TempFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Write, 1024 * 8);
                foreach (Byte[] chunk in WritingQueue.GetConsumingEnumerable())
                {
                    output.Write(chunk, 0, chunk.Length);
                }
                output.Close();
            }, TaskCreationOptions.LongRunning);

            Task timerAction = Task.Factory.StartNew(() =>
            {
                while (BytesLeft < ByteTotal)
                {
                    Thread.Sleep(10);
                    progressReport.Report((BytesLeft / (1024 * 1024)).ToString());
                }
            }, TaskCreationOptions.LongRunning);

            Task.WaitAll(readAction, encryptAction, writeAction, timerAction);


            // Delete the existing file if it exists
            File.Delete(DataFile.FullName);
            // Rename the temporary file created during encryption to it's final filename.
            File.Move(TempFile.FullName, DataFile.FullName);
        }

Progress.report只是一种更新ui线程的方法,目前已加密了多少字节。

如果我使用异步I / O,我该怎么写?

0 个答案:

没有答案