使用C#.NET 4.0
我公司的应用程序使用资源锁定器来保持记录不被同时编辑.我们使用数据库来存储锁的开始时间以及获取锁的用户.这导致在资源锁定器上执行以下(奇怪的?)dispose,这恰好是从析构函数调用的:
protected virtual void Dispose(bool disposing)
{
lock (this)
{
if (lockid.HasValue)
{
this.RefreshDataButtonAction = null;
this.ReadOnlyButtonAction = null;
try
{
**Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("@lockID", lockid.Value);
parameters.Add("@readsToDelete", null);
Object returnObject = dbio2.ExecuteScalar("usp_DeleteResourceLockReads", parameters);**
lockid = null;
}
catch (Exception ex)
{
Logger.WriteError("ResourceLockingController", "DeleteResourceLocks", ex);
}
finally
{
((IDisposable)_staleResourcesForm).Dispose();
_staleResourcesForm = null;
}
}
}
}
我担心粗体部分我们因为从数据库调用中记录了奇怪的“Handle is not initialized”异常.我在其他地方读到在Finalize()期间创建新对象是不安全的,但同样的规则是否适用于dispose()?在Dispose()期间是否有任何可能的副作用伴随创建新对象?
解决方法:
which happens to be called from a destructor
这是真正的问题.您不能假设* dbio2“对象本身尚未最终确定.最终化顺序在.NET中不具有确定性.结果看起来很像您描述的,dbase提供程序使用的内部句柄将被释放,因此”处理未初始化“预期异常.或者dbio2对象已经被处理掉了.
这在程序退出时尤其可能出错.当终结器线程的2秒超时时,你也会遇到问题,dbase操作可以轻松获得更多.
你根本无法依靠终结器来为你做这件事.您必须检查disposing参数,并且当它为false时不调用dbio2.ExecuteScalar()方法.这可能也结束了析构函数的用处.
标签:c,dispose 来源: https://codeday.me/bug/20190629/1324916.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。