C# Windows Service生成无效压缩包:日志文件夹压缩失败求助
解决Windows Service中生成无效压缩包的问题
你的问题核心出在Task的错误处理方式和路径拼接细节上,我来一步步帮你排查修复:
1. 立即Dispose Task导致压缩过程中断
你在创建Task后立刻调用task.Dispose()是关键问题——此时Task大概率还在后台执行压缩操作,Dispose会提前释放Task的资源,导致ZipFile还没完成压缩就被强制中断,最终生成损坏无效的zip包。
修复方案:
直接移除task.Dispose()调用。如果需要在压缩完成后执行后续操作(比如把压缩包移到C:\Backups),可以用ContinueWith或者更简洁的async/await风格:
// 推荐:async/await风格 private async void FileFoundInDrops(object sender, FileSystemEventArgs e) { var aggregatePath = new DirectoryInfo(@"C:\Aggregate"); if (e.FullPath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)) { await Task.Run(() => { try { var logDirPath = @"E:\Logs"; var timestamp = DateTime.Now.ToString("yyyyMMddHHmm"); // 用Path类安全拼接路径,避免分隔符错误 var zipFileName = $"{Path.GetFileName(logDirPath)}_{timestamp}.zip"; var zipFullPath = Path.Combine(Path.GetDirectoryName(logDirPath), zipFileName); ZipFile.CreateFromDirectory(logDirPath, zipFullPath); // 完成压缩后移动到备份目录 var backupDir = @"C:\Backups"; Directory.CreateDirectory(backupDir); // 确保备份目录存在 var destPath = Path.Combine(backupDir, zipFileName); File.Move(zipFullPath, destPath); } catch (Exception ex) { Log.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - ERROR: {ex.Message}\n{ex.StackTrace}"); } }); } }
2. 避免手动拼接路径的潜在错误
直接用字符串拼接路径(logDirectory + "_" + timeStamp + ".zip")容易出现分隔符混乱的问题,推荐用Path类的方法来安全生成路径,能彻底规避这类低级错误。
3. 防止FileSystemWatcher重复触发的并发冲突
FileSystemWatcher可能对同一个文件触发多次事件(比如文件创建过程中会触发Created、Changed等多次),这会导致多个Task同时压缩E:\Logs目录,引发文件锁定冲突或压缩包损坏。
修复方案:添加锁机制,确保同一时间只有一个压缩任务在执行:
// 全局锁对象,确保压缩操作串行执行 private static readonly object _compressLock = new object(); private async void FileFoundInDrops(object sender, FileSystemEventArgs e) { var aggregatePath = new DirectoryInfo(@"C:\Aggregate"); if (e.FullPath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)) { await Task.Run(() => { lock (_compressLock) { try { var logDirPath = @"E:\Logs"; var timestamp = DateTime.Now.ToString("yyyyMMddHHmm"); var zipFileName = $"{Path.GetFileName(logDirPath)}_{timestamp}.zip"; var zipFullPath = Path.Combine(Path.GetDirectoryName(logDirPath), zipFileName); ZipFile.CreateFromDirectory(logDirPath, zipFullPath); var backupDir = @"C:\Backups"; Directory.CreateDirectory(backupDir); var destPath = Path.Combine(backupDir, zipFileName); File.Move(zipFullPath, destPath); } catch (Exception ex) { Log.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - ERROR: {ex.Message}\n{ex.StackTrace}"); } } }); } }
4. 额外排查:文件锁定问题
如果上述修复后仍有问题,检查E:\Logs下的日志文件是否被其他进程(比如服务本身或日志写入程序)独占锁定。ZipFile压缩时需要读取文件,若文件被锁定会抛出异常,你可以通过日志查看具体错误信息。
按照这些步骤修改后,应该能彻底解决压缩包无效的问题。
内容的提问来源于stack exchange,提问作者CodePull
相关产品推荐
相关产品推荐

