简体   繁体   English

当多个客户端可能使用该资源时,该如何处置?

[英]How to dispose the resource when it might be used by multiple clients?

我正在实现一种流水线模式,该资源(例如一个图像对象)将通过该流水线,而且我不知道有多少客户端持有该资源,那么配置该资源的更好方法是什么?

I think you only really have two options. 我认为您真的只有两个选择。

1) Someone owns that object, and controls access to it. 1)有人拥有该对象,并控制对它的访问。 Therefore, it must dispose of it when it has determined that no one should need it anymore. 因此,当它确定不再需要它时,必须将其丢弃。 This is good old manual resource management. 这是很好的旧的手动资源管理。

2) You don't dispose it, and have to wait for the GC to collect and call the finalizer on the instance. 2)您不需要处理它,而必须等待GC收集并在实例上调用终结器。 Any object that implements IDisposable should also have a finalizer that handles the sam elogic if Dispose is not called. 如果未调用Dispose,则实现IDisposable的任何对象还应具有处理sam elogic的终结器。 If you call dispose, then this extra step does not have to be taken, and GC is more efficient. 如果调用dispose,则不必执行此额外步骤,并且GC效率更高。

The way that springs immediately to mind is to wrap the resource inside some form of reference counting "wrapper" so that you can dispose of it when the reference count has released zero. 立即想到的方式是将资源包装在某种形式的引用计数“包装器”中,以便您可以在引用计数释放为零时处置它。

Something like this: 像这样:

public class RefCountingWrapper<T> where T:IDisposable, new()
{
    private int referenceCount = 0;
    private T resource;

    public RefCountingWrapper(T item)
    {
        resource = item;
    }

    public T Acquire()
    {
        referenceCount++;
        return resource;
    }

    public void Release()
    {
        referenceCount--;
        if (referenceCount <= 0)
        {
            resource.Dispose();
        }
    }
}

Caveats that apply: 适用的注意事项:

  • Anyone that has taken the result of Acquire and holds a reference to it will now hold a reference to something that has been disposed (that said, once they've released it, they shouldn't try and access it!). 现在,任何获取了Acquire结果并对其进行引用的人都将引用已处置的内容(也就是说,一旦发布了它们,他们就不应尝试访问它!)。
  • This is vulnerable to people not matching their Acquire's and Release's, thus could cause others to encounter a disposed object inadvertantly. 这容易受到无法与“获取”和“发布”匹配的人的攻击,从而可能导致其他人无意间遇到被处置的对象。 That shouldn't be a massive issue if you control all the code that utilises the resource/calls Acquire/Release though. 如果您控制所有利用资源/调用获取/发布的代码,那应该不是一个大问题。
  • You'll probably want to put some locking round the Acquire/Release methods if there's even the slightest hint of multi-threaded code going near something wrapped by this. 如果甚至丝毫暗示着多线程代码都在此包装的东西附近,那么您可能希望对Acquire / Release方法进行一些锁定。
  • There's absolutely nothing to stop the code that's using the Acquired resource from calling .Dispose() on the underlying resource 绝对没有什么可以阻止使用Acquired资源的代码对基础资源调用.Dispose()的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM