为什么我没有看到IDisposable实现并发的任何实现?

dro*_*ron 16 c# idisposable thread-safety

当我查看示例实现时IDisposable,我还没有发现任何线程安全.为什么IDisposable没有实现线程安全?(相反,调用者有责任确保只调用一个线程Dispose()).

Ben*_*Ben 30

在完成对象之前,不应丢弃对象.如果有其他线程引用该对象,并且他们可能想要调用其方法,则不应该将其处理掉.

因此,Dispose不必是线程安全的.

  • 在某些情况下,强制放弃阻塞I/O操作的首选方法(如果不是唯一的方法)是从它下面"处理"连接; 这样的处理只能*从外部线程发生(被阻塞的线程在被阻塞时不能做任何事情).外部线程可能决定"处理"连接,就像连接正在完成其工作一样,被阻塞的线程决定"自己处理"它. (2认同)

Dan*_*ant 6

线程安全的Dispose模式的唯一真正好处是可以保证在跨线程滥用的情况下获得ObjectDisposedException而不是潜在的不可预测的行为.请注意,这意味着该模式需要的不仅仅是线程安全的Dispose; 它要求所有依赖于未处置的类的方法与处理机制正确联锁.

这样做是可能的,但要覆盖仅在出现使用错误(即错误)时才会出现的边界情况需要付出很多努力.


Sim*_*eon 2

Brian Lambert 撰写了一篇题为IDisposable 的简单且完全线程安全的实现的博客文章。
它包含以下实现:

using System;
using System.Threading;

/// <summary>
/// DisposableBase class. Represents an implementation of the IDisposable interface.
/// </summary>
public abstract class DisposableBase : IDisposable
{
    /// <summary>
    /// A value which indicates the disposable state. 0 indicates undisposed, 1 indicates disposing
    /// or disposed.
    /// </summary>
    private int disposableState;

    /// <summary>
    /// Finalizes an instance of the DisposableBase class.
    /// </summary>
    ~DisposableBase()
    {
        // The destructor has been called as a result of finalization, indicating that the object
        // was not disposed of using the Dispose() method. In this case, call the DisposeResources
        // method with the disposeManagedResources flag set to false, indicating that derived classes
        // may only release unmanaged resources.
        this.DisposeResources(false);
    }

    /// <summary>
    /// Gets a value indicating whether the object is undisposed.
    /// </summary>
    public bool IsUndisposed
    {
        get
        {
            return Thread.VolatileRead(ref this.disposableState) == 0;
        }
    }

    #region IDisposable Members

    /// <summary>
    /// Performs application-defined tasks associated with disposing of resources.
    /// </summary>
    public void Dispose()
    {
        // Attempt to move the disposable state from 0 to 1. If successful, we can be assured that
        // this thread is the first thread to do so, and can safely dispose of the object.
        if (Interlocked.CompareExchange(ref this.disposableState, 1, 0) == 0)
        {
            // Call the DisposeResources method with the disposeManagedResources flag set to true, indicating
            // that derived classes may release unmanaged resources and dispose of managed resources.
            this.DisposeResources(true);

            // Suppress finalization of this object (remove it from the finalization queue and
            // prevent the destructor from being called).
            GC.SuppressFinalize(this);
        }
    }

    #endregion IDisposable Members

    /// <summary>
    /// Dispose resources. Override this method in derived classes. Unmanaged resources should always be released
    /// when this method is called. Managed resources may only be disposed of if disposeManagedResources is true.
    /// </summary>
    /// <param name="disposeManagedResources">A value which indicates whether managed resources may be disposed of.</param>
    protected abstract void DisposeResources(bool disposeManagedResources);
}
Run Code Online (Sandbox Code Playgroud)

然而,绝对和完整的整体性在博客和此处的评论中都存在争议。

  • @Hans:这并不是根本错误;而是。完全有可能多个线程希望在它们同时完成对象时在它们之间协商谁可以处置该对象。**该协商协议必须由线程安全部分组成。** Brian 的博客不是“胡言乱语”。 (3认同)
  • @Hans我没有看到任何其他方式来阅读你最初的评论。“这个胡言乱语”还有什么胡言乱语? (3认同)