当前位置: 代码迷 >> C# >> 程序不测推出,文件流存储
  详细解决方案

程序不测推出,文件流存储

热度:52   发布时间:2016-05-05 04:59:43.0
程序意外推出,文件流存储
由于是程序员初学者,写出来的程序,用户误操作会引发相对比较多的意外退出。

那么问题来了,由于文件流没有及时关闭,那么之前存储的数据就会丢失。

我想知道大家是怎么应付这种情况的?

我现在暂时用的解决办法是:
1.尽量catch到每一个异常,但肯定还是会存在捕获不到的异常,而且我目前比较浮躁,暂时比较烦去处理这些细节问题。
2.不断的开启和关闭数据流,每存一部分数据就关闭,然后再开启。这样可能会大大影响效率?底层基础比较弱,我也没有仔细去测试。
------解决思路----------------------
你不可能给每一行都写上try...catch吧?即使你写了,你除了再次多余地抛出异常或者给用户一个“出错了”这样的提示,你能“解决”什么问题吗?

try...catch不能解决任何问题。所以把这个说成是解决了问题,是自欺欺人和欺瞒上级检查的做法(假设上级根本不深入测试是否数据混乱)。如果你某条语句try...catch之后还继续执行下一条语句,那么你的程序将在滚雪球一般的多么巨大的错误数据下继续处理和保存完全错误的数据啊?!

真正的做法,是一个程序只有在表现层——最外层——统一地捕获异常,然后给用户提示。而在内部各层并不try...catch。

并且,只有在Release版本中才会启用这个(只有几行代码的)表现层异常处理程序。在Debug版本中绝不启用它。

在Debug版本,也就是开发和测试阶段所使用的程序版本,它的目的就是尽可能早地重复发现你发现的这种Bug。这个阶段发现Bug是“万幸”,发现了这类问题那么后边的工作就不用做了,就应该先把这个Bug消灭掉,才敢于进行接下来的开发工作。因此如果说“不断的开启和关闭数据流,每存一部分数据就关闭,然后再开启”这能让Bug(在Debug,也就是不靠表现层给用户一个伪装的“友好提示”时)被消灭掉,谁还扯什么“大大影响效率”的淡呢?谁不想弄一个“又不影响效率又没有Bug的程序呢”?如果连正确性都没有了,纠结“效率”不就多余了嘛!

只有极个别的(但是属于正常业务流程)情况下,由于.net类库没有封装好异常隔离机制,我们才需要写try...catch。比如你的代码中有整数运算
a = b /c;
这样的语句,那么你就必须写
if(c!=0)
这样的判断语句,走正常业务流程设计,而不应该写什么try...catch。

所以上述两个Debug原则(不要写try...catch、要保证程序稳定运行)都需要遵守。


------解决思路----------------------
文件流有一个flush方法。每次你写完了就flush一次,那么内存里的内容就被写到磁盘上了。即使程序意外退出了,之前的内容已经在磁盘上了,所以不会丢失。
------解决思路----------------------
频繁Flush当然会影响些性能,不过只要在能够接受的范围内就可以,像StreamWriter类也有AutoFlush属性自动Flush。也可以自己设置FileStream的buffer的大小,它默认是4KB。(这个Flush也不能确保写到磁盘,不过一般场合就够了)

一般情况,用户的非法操作导致的异常是在UI线程。如果是winform可以使用Application.ThreadException截获所有UI上的异常。类似的wpf上有Dispatcher.UnhandledException。这种UI线程上的截获一般更"靠近"异常发生的地方,所以先通过这些来统一处理。这样子程序可能还能恢复成可用的状态。

然后,可以使用AppDomain的UnhandledException事件,统一对没有截获的异常做处理。但是这个时候已经无法阻止程序退出了。当然如果是被任务管理器强制结束,那这些事件都没有。

最理想的方式是把UI和接收数据写文件的进程彻底隔离。使用一个新的进程来接收数据和写文件,UI只是和这个进程进行进程间交互。那么UI的异常只要不给工作进程发错误的指令就没有关系。这样也利于一组人维护底层,另一组人维护UI,甚至做多版本UI,比如迅雷就是这么做的。
  相关解决方案