异步调用就是启动了新的线程,主线程与方法线程并行执行,一个可以无需等待被调用函数的返回值就让操作继续进行的方法,异步调用节约了大量的等待时间,客户体验感直线上升,但是异步调用也有令人头疼的时候,分享一个我最近遇到的问题。
背景:C#开发,客户要求增加档案批量修改功能,模式为在目录上选中需要维护的数据后点击维护按钮弹出变更表,将目录数据带入变更表,在变更表上修改需要维护的数据再保存,保存后将变更表页面关闭然后打开审批表,将变更后的数据项保存到审批表中进行审批。
问题:在码代码时为了提高速度,变更表close()方法(关闭事件)与审批表openPage()事件用异步调用处理,都是在变更表点击onSave()事件后触发。写好后本地测试时毫无问题、一切正常,然后丢到测试服务器,测试工程师测试也是毫无问题就升级到正式服务器上去了,然后问题就出现了。偶尔出现"未将对象引用设置到对象的实例",空引用了,而且不经常出现,客户反馈过来后我们测试服务器多次测试也有这样情况出现,最尴尬的就是本地断点调试怎么也不能复现问题,异常不复现就没办法解决啊,拿到log日志后看到是审批表openPage()后校验单据类型以及时间戳时单据类型和时间戳都是空值,按道理讲不会出现空值,都是单据加载后这些数据就load上了。
处理:一时间找不到问题症结,本地测试确实单据打开后数据项就load上了,就请教了下师傅,师傅看了一遍在经验之上就确定是异步调用出的问题,异步调用关闭事件执行将数据项全部置为null,所以单据打开之后进行校验就出现空引用了,异步调用时间执行快慢导致了bug会ouer出现,本地断点一定不会复现问题,断点的时间程序早就执行过去了。最后将close()事件里面的置null方法前加了个:Thread.Sleep(1000);问题得以解决。