gpt4 book ai didi

c# - Dispose() 应该创建对象的新实例吗?

转载 作者:行者123 更新时间:2023-11-30 12:10:06 26 4
gpt4 key购买 nike

使用 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;
}
}
}
}

我很关心粗体部分,因为我们一直在记录来自数据库调用的奇怪的“句柄未初始化”异常。我在别处读到在 Finalize() 期间创建新对象是不安全的,但是同样的规则是否适用于 dispose()?在 Dispose() 期间创建新对象是否有任何可能的副作用?

最佳答案

which happens to be called from a destructor

这才是真正的问题。您不能假设 *dbio2"对象本身尚未完成。.NET 中的完成顺序不确定。结果看起来很像您描述的,数据库提供程序使用的内部句柄将被释放,因此“句柄未初始化”异常是预期的。或者 dbio2 对象只是已经被释放。

这在程序退出时特别容易出错。当终结器线程超时 2 秒时,您还会遇到问题,数据库操作很容易占用更多时间。

你不能简单地依赖终结器来为你做这件事。您必须检查disposing 参数,并且在它为false 时调用dbio2.ExecuteScalar() 方法。这可能也结束了析构函数的用处。

关于c# - Dispose() 应该创建对象的新实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19433116/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com