我需要使用语句来锁定处置资源,这是我的定制解决方案的健壮性

本文关键字:我的 健壮性 解决方案 资源 语句 锁定 | 更新日期: 2023-09-27 18:19:09

我的情况是,清理非托管资源是一个关键部分。为了解决这个问题,我改变了这个…

void SomeMethod()
{
    //work
    using (var doc = SpreadsheetDocument.Open(results.FileName, true))
    {
        //use doc.
    }
}
这个…

public static readonly object Locker = new object();
void SomeMethod()
{
    //work
    {//scoping doc
        var doc = SpreadsheetDocument.Open(results.FileName, true);
        try
        {
             //use doc
             //At some point wrapping a critical section via lock(Locker) 
        }
        finally
        {
            lock (Locker)
            {
                if (doc != null) ((IDisposable)doc).Dispose();
            }
        }
    }
}

,我认为,这是一个丑陋而脆弱的解决方案。因此,我将其更改为以下内容:

public static readonly object Locker = new object();
void SomeMethod()
{
    //work
    CustomUsingWithLocker(SpreadsheetDocument.Open(results.FileName, true), Locker, doc =>
    {
        //use doc
        //At some point wrapping a critical section via lock(Locker) 
    });
}
public static void CustomUsingWithLocker<T>(T resource, object locker, Action<T> body)
    where T : class, IDisposable 
{
    try
    {
        body(resource);
    }
    finally
    {
        lock (locker)
        {
            if (resource != null) resource.Dispose();
        }
    }
}

这个定制的解决方案健壮吗?我能改进它吗?它是否保证释放任何非托管资源,如内置的Using语句?

我需要使用语句来锁定处置资源,这是我的定制解决方案的健壮性

这里的前提似乎是Dispose被多个线程多次调用。如果是这样,那就改变这个前提。即使doc被传递给…在另一个线程中使用它的某个地方,其他地方不负责处理它,也不应该处理它。找到它被处置的地方除了using的结尾,并改变它不这样做。

如果Dispose没有在其他地方被调用,并且您只是有一个非线程安全的Dispose方法,不应该从多个线程访问(即使您的代码目前足够聪明,不能这样做),并且您只是试图应用良好的防御性编程,我认为可以安全地说这里不需要这样做。在这个特定的上下文中,只有一个线程应该负责处理对象,这是该方法的有效约束。