在 C# 中压缩文件夹时窗体冻结 x 秒

Form freezes for x seconds when zipping a folder in C#

我有一个 windows 表单项目,我在其中压缩了一个文件夹。表格冻结3-4秒后操作完成

private void ZipSafe(string p_FolderName, string p_ArchiveName)
{
    try
    {
        if (File.Exists(p_ArchiveName))
            File.Delete(p_ArchiveName);

        string[] l_DataSet = Directory.GetFiles(p_FolderName, "*.txt");
        using (ZipArchive l_Zip = ZipFile.Open(p_ArchiveName, ZipArchiveMode.Create))
        {
            foreach (string l_File in l_DataSet)
            {

                using (FileStream l_Stream = new FileStream(l_File, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
                {
                    ZipArchiveEntry l_ZipArchiveEntry = l_Zip.CreateEntry(Path.GetFileName(l_File), CompressionLevel.Optimal);
                    using (Stream l_Destination = l_ZipArchiveEntry.Open())
                    {
                        l_Stream.CopyTo(l_Destination);
                    }
                }
            }
            l_Zip.Dispose();
        }
    }
    catch (System.Exception e)
    {
        using (StreamWriter sw = new StreamWriter(@"C:\Users\**\Documents\ErrorZip.txt"))
        {
            string l = e.ToString();
            sw.WriteLine(l);
            sw.Close();
        }
    }
}

我在点击按钮时调用了这个函数。我试图使用调试器来了解这里发生了什么。冻结发生在 for-each 循环的第二次迭代期间,对于以下代码行:

l_Stream.CopyTo(l_Destination);

我知道有很多 post 关于在 c# 中压缩文件夹,我仍然希望我的问题是相关的。任何帮助都会很棒,提前谢谢你。

祝你有美好的一天, vbvx

发生这种情况是因为您正在使用 UI 线程执行操作。您需要 运行 在另一个线程上执行操作以使 UI 线程空闲(即阻止您的应用程序冻结)。

尝试:

private void ZipSafe(string p_FolderName, string p_ArchiveName)
{
Task.Factory.StartNew(() =>
{
try
{
    if (File.Exists(p_ArchiveName))
        File.Delete(p_ArchiveName);

    string[] l_DataSet = Directory.GetFiles(p_FolderName, "*.txt");
    using (ZipArchive l_Zip = ZipFile.Open(p_ArchiveName, ZipArchiveMode.Create))
    {
        foreach (string l_File in l_DataSet)
        {

            using (FileStream l_Stream = new FileStream(l_File, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite))
            {
                ZipArchiveEntry l_ZipArchiveEntry = l_Zip.CreateEntry(Path.GetFileName(l_File), CompressionLevel.Optimal);
                using (Stream l_Destination = l_ZipArchiveEntry.Open())
                {
                    l_Stream.CopyTo(l_Destination);
                }
            }
        }
        l_Zip.Dispose();
    }
}
catch (System.Exception e)
{
    using (StreamWriter sw = new StreamWriter(@"C:\Users\**\Documents\ErrorZip.txt"))
    {
        string l = e.ToString();
        sw.WriteLine(l);
        sw.Close();
    }
}
}
}