项目中计数不同步和日志记录引发的BUG

来源:互联网 发布:c语言逻辑运算 编辑:程序博客网 时间:2024/05/22 03:20

项目开发前期早就完成了,但投入实际使用时出现了些很小却很头痛的问题。其中最值得注意又最容易忽略的两点,这里作一下记录。

第一:计数不同步

在项目投入使用后,发现数据总是会不同步,查遍了代码,从理论上,都不可能发生,但是实际上却又发生了。后来想起了以前看到过的文章,有提到多线程内操作同一个变量进行加减时,变量可能会不一致。按照这个思路,去查了一下日志记录,果然发现计数有莫名跳动的情况。比如数字本来是从1自增到10的,可是中间却出现了断层(比如7、9、10),而有时甚至还出现了越界(比如计数上限是10,如果大于10会内部作了处理,会自动返回,但结果在小于等于10的后续逻辑中发现了11的记录)。那这个要怎么解决呢?之前在看COM组件开发的《COM技术内幕》时提到了采用内置的自增和自减函数的做法(InterlockedIncrement()和InterlockedDecrement()),不过这是C++的做法,那C#有没有类似的呢?搜了一下,果然有,对就的是Interlocked.Increment()和Interlocked.Decrement()(可以参见http://msdn.microsoft.com/zh-cn/library/system.threading.interlocked%28v=VS.100%29.aspx),所不同的是,C#里是将这两个函数放到了Interlocked类里面去了。这样处理之后,计数不同步的问题消失了。不过这样处理有一个不足的,会降低性能。

第二:日志记录太频繁

计数不同步的问题得以发现,是因为作了日志记录。当时心里暗喜,幸好作了这么详细的日志记录。但是后来项目继续运行时, 发现了新问题,虽然计数是同步了,但是数据在界面上的更新相差太大,起初是几个,后面竟然达到了200个之多,这对于客户肯定是无法接受的。于是又是查找、查找,同样是逻辑上没有问题,但问题又出现了,思来想去,这极可能是更新界面占用了太多的时间片,想着是不是用异步来处理更好。一查代码,发现已经是begininvoke的异步处理了。虽然异步处理会相对滞后一步,但也不至于会滞后那么多,所以问题应该不在这儿。继续查找,实在找不到问题点了,后面拿了客户的数据库备份来还原,想再查查日志看看。在还原数据时,猛然发现了一个问题,怎么这备份文件这么大,竟然达到了近2G。客户用的是SQL EXPRESS版本,对数据大小有限制,这会不会导致数据读写过慢?

那是什么原因导致数据量增长的这么快?一查数据库的表,发现日志数据增长的实在太快,虽然系统内部对日志作了处理(超过半年的日志会自动删除),但这还是增长的太快了。再查增长这么快的日志内容,对应到代码上,发现是一段关于计数记录的日志增加的最快,几乎是100毫秒就会产生一笔记录,这么频繁的操作数据库,数据自然增长很快。果断将可以不记录的部分屏蔽掉,然后运行。发现界面数据与实据输出的数据几乎同步,最多相差一两个,这么说,问题应该就是这了。

可是为什么数据库的操作会影响到界面的更新呢?这源于更新界面时,出于交互需要必须从数据库获取数据。

所以在以后的项目开发中,一定要给自己提个醒,在发布时,要把调试日志和不必要记录及可屏蔽的日志给屏蔽掉,以免引来恶果。

修复了这两个问题后,项目已经正常运行了几个月了,这里作一个记录。