注意异步方法中全局变量生命周期
问题症状:Web程序通过异步把文件缓存成静态HTML页面时候有时候,有时候会缓存成功有时候缓存失败。
解决思路:
- 这是一个比较久的问题,但一直没有时间来检查原因,正好今天在优化缓存机制的时候就检查一下原因了.在代码中写入日志记录。
/// <summary> /// 生成静态文件 /// </summary> /// <param name="htw"></param> /// <param name="fileHtml"></param> /// <param name="cachePath"></param> public void GenerateStaticHtml(HtmlTextWriter htw, string fileHtml, string cachePath) { string m_FileName = GetCacheStaticHtmlName(); if (PageIsCache == true && m_FileName.Length > 0) { string fullFileName = Path.Combine(cachePath, m_FileName); try { using (StreamWriter wter = new StreamWriter(fullFileName, false, System.Text.Encoding.UTF8)) { wter.Write(fileHtml); wter.Flush(); wter.Close(); wter.Dispose(); } } catch (System.Exception ex) { Logger.Debug("生成缓存错误", ex); } } htw.Close(); htw.Dispose(); }
先是在异常捕获地方加入finally 测试是不是每一次都执行了。结果发现没有生成的时候没有执行finally ,这就让人蛋痛了。难道是异步没有执行?
还是没有进入if语句。继续在if语句前面加记录日志调试!结果还是没有执行!这回就猜到大概问题是出在 GetCacheStaticHtmlName()函数中了.
看到代码后情况就清楚了。
if (Request.RawUrl == "/") { strHtmlName = "default.html"; }
Request对象的问题.肯定是异步执行时候页面已经执行了Response.End()释放掉了,加上try catch 记录日志一看,2012-12-06 15:05:55,104 [23] INFO Tools.Logger [(null)] - 获取文件名称出错:
System.Web.HttpException (0x80004005): 请求在此上下文中不可用
在 System.Web.UI.Page.get_Request()修改代码把缓存文件名传递进来后正常了。
总结:
- 这个问题看到在写代码的时候首先是没有保证一个函数只处理一件事件,例如:获取缓存路径的应该放到写缓存的外面.作为一个参数传递进来
- 异步方法中一定要注意使用到的全局变量的生命周期
- 由于项目比较大,解决这个问题我没有使用调试的方式,Debug断点调试也许就没有这个问题了。使用日志记录调试信息提高了不少效率
作者:xuchengzone
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.