【问题标题】:CryptoStream ReportProgress ProgressBar C#CryptoStream ReportProgress 进度条 C#
【发布时间】:2016-04-23 10:34:12
【问题描述】:

所以我正在尝试加密一些文件并且它工作正常,但是当我尝试包含一个进度条来显示大文件的距离时,例如 100mb-1gb 文件,性能被大幅降低并且非常慢。我假设它是因为 ReportProgress 被快速调用,所以我在秒表中添加了仅每 2 秒更新一次,但这导致它工作得更快(如果不调用 reportProgress 仍然没有那么快),但有时也不会更新进度条完全没有。

using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
            {
                using (CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
                    {
                        int data;
                        int test = 0;
                        Stopwatch stopw = new Stopwatch();
                        stopw.Start();
                        while ((data = fsIn.ReadByte()) != -1)
                        {
                            cs.WriteByte((byte) data);
                            test++;
                            if (stopw.Elapsed.Seconds > 2)
                            {
                                stopw.Reset();
                                backgroundWorker1.ReportProgress((int) fsIn.Length);

                            }
                        }
                        stopw.Stop();
                    }
                }
            }

例如,删除backgroundWorker1.ReportProgress((int) fsIn.Length); 行后,文件可能需要 5 秒,但添加后,最终需要 20 秒。

我可以做些什么来改进它并使其更快?

【问题讨论】:

    标签: c# filestream cryptostream


    【解决方案1】:

    我的建议是不要使用秒表,而是继续使用字节数。也许检查每个字节后经过的秒表需要很长时间(虽然似乎不太可能,但谁知道)。此外,在 while 循环之外获取一次 fsIn.Length

    using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
    {
        using (CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write))
        {
            using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
            {
                int data;
                long test = 0;
                long total = fsIn.Length;
                while ((data = fsIn.ReadByte()) != -1)
                {
                    cs.WriteByte((byte) data);
                    test++;
                    if (test % 10000 == 0)
                    {
                        backgroundWorker1.ReportProgress((int) (test * 100 / total));
    
                    }
                }
            }
        }
    }
    

    还要确保ReportProgress 事件处理程序中的代码不是罪魁祸首。你不想在那里做任何昂贵的事情。

    【讨论】:

    • 看起来应该可以,但是进度条根本没有变化,一直保持在 0%
    • oops, test is int....尝试将报告进度参数更改为(int)(test * 100 / total)
    • 它通过了大约 1/4,然后在 Value of '-34' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'. 上失败了
    • 您的文件有多大?也许乘以 100 会溢出 int?尝试将 test 和 total 变量更改为 long。
    • 修复了将它们更改为长的
    猜你喜欢
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多