为何仅添加try/catch时Stream相关代码才能正常运行?
问题分析与解决方案
首先,代码中的冗余/风险点
- 你创建了
JsonTextReader但完全没有使用,这部分代码可以直接删除,不影响任何功能。 - 在
using块内手动调用Stream.Close()是多余的:using语句本质是try-finally结构,会自动在块结束时调用流的Dispose()方法,而Dispose()内部会负责关闭流。手动提前关闭流,可能导致后续Dispose()执行时抛出异常,干扰正常的异常捕获逻辑。
核心问题原因推测
移除内部try/catch后控制台无输出、外层try/catch未捕获异常,大概率是以下两种情况:
- 异常被
using的finally块覆盖
当反序列化抛出异常后,程序会进入using的finally块执行Dispose()。由于你手动关闭了流,Dispose()再次尝试关闭流时可能抛出新的异常,此时原反序列化的异常会被丢弃,外层catch只能捕获到Dispose()的异常。如果这个Dispose()的异常被.NET内部机制静默处理,就会出现外层无捕获、程序继续执行的情况。 - 控制台输出缓冲未刷新
反序列化抛出异常后,当前代码块终止执行,之前Console.WriteLine(JsonString)的输出可能还停留在控制台缓冲区中,没有及时显示到界面上,导致你误以为没有输出。
修复步骤
- 清理冗余代码,移除手动关闭流的操作
简化后的代码:using (StreamReader stream = new StreamReader(CombinedFile)) { string jsonString = stream.ReadToEnd(); Console.WriteLine(jsonString); Console.Flush(); // 强制刷新控制台输出,避免缓冲问题 InsertList = JsonConvert.DeserializeObject<List<KeyValuePair<int, object>>>(jsonString); Console.WriteLine("---------------------------------------------------------------" + InsertList.Count); } - 确保外层
try/catch完全包裹代码块
检查外层try的范围,确保整个using块都在try内部,避免遗漏:try { using (StreamReader stream = new StreamReader(CombinedFile)) { string jsonString = stream.ReadToEnd(); Console.WriteLine(jsonString); Console.Flush(); InsertList = JsonConvert.DeserializeObject<List<KeyValuePair<int, object>>>(jsonString); Console.WriteLine("---------------------------------------------------------------" + InsertList.Count); } } catch (Exception ex) { Console.WriteLine($"捕获到异常: {ex.ToString()}"); Console.Flush(); } - 排查未捕获的异常
如果上述操作后仍有问题,添加全局异常处理来捕获所有未处理的异常:// 在程序启动时添加 AppDomain.CurrentDomain.UnhandledException += (sender, args) => { Console.WriteLine($"未处理全局异常: {args.ExceptionObject.ToString()}"); Console.Flush(); };
为什么内部try/catch时正常?
内部try/catch捕获了反序列化的异常,阻止了异常传递到using的finally块,因此Dispose()不会因为流已提前关闭而抛出额外异常,控制台输出也能正常刷新,后续代码自然能继续执行。
内容的提问来源于stack exchange,提问作者tlf
相关产品推荐
相关产品推荐

