UWP Release模式下日志文件为空(大小0KB)问题求助
UWP Release模式下DataWriter写入日志生成0KB文件问题
问题现象
使用StorageFile类和DataWriter实现UWP应用日志记录功能时,Debug调试模式下生成的日志文件大小为50KB,内容可正常写入;切换到Release发布模式后,日志文件大小始终为0KB,无任何内容写入。
原实现代码:
var ptLogFileName = GetLogFileName(prnTicketLogType, ".txt"); StorageFile ptLogStorageFile = await fileFolderPath.CreateFileAsync(ptLogFileName, CreationCollisionOption.ReplaceExisting); var stream = await ptLogStorageFile.OpenAsync(FileAccessMode.ReadWrite); using (var outputStream = stream.GetOutputStreamAt(0)) { using (var printTicketWriter = new DataWriter(outputStream)) { printTicketWriter.WriteString(GlobalConstants.KEY_COPIES + ":" + copiesVal + Environment.NewLine); . . . // 省略其余日志写入逻辑 await printTicketWriter.StoreAsync(); await outputStream.FlushAsync(); } } stream.Dispose();
问题根因
Release模式下UWP默认启用.NET Native工具链编译,会执行比Debug模式激进得多的生命周期优化,原代码存在三个隐患:
- 最外层文件流未纳入
using块自动托管,手动调用Dispose()的时机在编译优化下可能早于异步写入实际完成时间,直接中断写入流程 DataWriter仅调用StoreAsync()无法保证缓冲区内容在优化逻辑下被完整传递到底层文件流,嵌套的流对象可能在Flush操作完成前被GC提前回收- 未显式指定
DataWriter编码格式时,Debug与Release模式下的默认编码解析逻辑存在差异,极端场景会直接导致写入失败
修复方案
- 将所有层级的流都纳入
using块做生命周期托管,移除手动调用的Dispose(),保证流对象在整个写入流程中不会被提前释放 - 显式指定
DataWriter的编码格式,消除不同编译模式下的默认值差异 - 写入完成后依次执行
StoreAsync、DataWriter.FlushAsync,调用DetachStream()分离写入器与流的引用,最后执行输出流的FlushAsync,确保所有缓冲区内容被完整写入文件
修复后代码:
var ptLogFileName = GetLogFileName(prnTicketLogType, ".txt"); StorageFile ptLogStorageFile = await fileFolderPath.CreateFileAsync(ptLogFileName, CreationCollisionOption.ReplaceExisting); // 最外层文件流纳入using托管 using (var stream = await ptLogStorageFile.OpenAsync(FileAccessMode.ReadWrite)) { using (var outputStream = stream.GetOutputStreamAt(0)) { using (var printTicketWriter = new DataWriter(outputStream)) { // 显式指定编码,消除模式差异 printTicketWriter.UnicodeEncoding = UnicodeEncoding.Utf8; printTicketWriter.ByteOrder = ByteOrder.LittleEndian; printTicketWriter.WriteString(GlobalConstants.KEY_COPIES + ":" + copiesVal + Environment.NewLine); . . . // 其余日志写入逻辑保持不变 await printTicketWriter.StoreAsync(); // 刷入DataWriter自身缓冲区 await printTicketWriter.FlushAsync(); // 分离写入器与流,避免Dispose写入器时影响流状态 printTicketWriter.DetachStream(); } // 最终将输出流内容刷入磁盘文件 await outputStream.FlushAsync(); } }
如果修复后仍存在偶发写入失败,可以在日志写入逻辑外层加try-catch捕获异常,Release模式下可以通过
Debug.Writeline输出异常信息定位具体问题。
内容的提问来源于stack exchange,提问作者Samyraj
相关产品推荐
相关产品推荐

