如果我需要一个Disposable项目整个运行怎么办?

时间:2013-08-24 12:36:43

标签: c# multithreading dispose

如果我的应用程序的整个运行需要一个Disposable项目怎么办? 在某些情况下,这似乎是必要的,例如,如果我想同步2个线程: System.Collections.Concurrent.BlockingCollection。

如果一个Thread使用Using,并且处理它,而另一个Thread无法关闭或正在等待BlockingCollection(你可以设置一个超时),那么它将获得一个Disposed Exception。

如果这是真的,可能会有更多的情况,那么有没有办法绕过这个,或者我应该简单地在Initialization上创建对象,并在Close上处理它?<​​/ p>

编辑:以下是Visual Studio在使用Disposable项目时告诉我的内容。

首先我如何使用它,在一个例子中:

private void Initialize()
        {
            Queue = new System.Collections.Concurrent.BlockingCollection<byte[]>();
            Queue.Dispose();
        }

我明白了:

warning : CA2213 : Microsoft.Usage : 'Capture' contains field 'Capture.Queue' that is of IDisposable type: 'BlockingCollection<byte[]>'. Change the Dispose method on 'Capture' to call Dispose or Close on this field.

所以这让我感到困惑。我告诉它在制作完成后立即处理,它仍然要我处理它:S

编辑2:

这是处理整个应用程序运行时应该处于活动状态的对象的正确方法吗?

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
        Queue.Dispose();
    }
    base.Dispose(disposing);
}

如您所见,我在那里添加了Queue。

这似乎不对,使用Designer.cs文件并在components.Dispose();

下添加东西感觉很奇怪。

但希望这是正确的。

3 个答案:

答案 0 :(得分:3)

表单项目项模板让程序员遇到麻烦。他们知道您不应该编辑Designer.cs文件。但事实并非如此直截了当。打开文件并记下区域:

    #region Windows Form Designer generated code

那是你不应该搞乱的代码。请注意,Disposing(bool)覆盖高于此区域。这意味着编辑那个就好了。

最好的办法是将Designer.cs文件中的Dispose()方法简单地剪切/粘贴到表单的源代码文件中。现在您可以顺利完成分析仪的建议:

    protected override void Dispose(bool disposing) {
        if (disposing) Queue.Dispose();
        if (disposing && (components != null)) {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

答案 1 :(得分:1)

仅仅因为物品是一次性的,并不意味着你必须处理它!不要使用using块:这将在对象超出范围后将其处置掉。只需正常实例化对象并在您自己的好时机中处理它(或者,如果您希望在应用程序的整个生命周期中使用它,则永远不会处理它。)

答案 2 :(得分:1)

Visual Studio警告您,您的对象(名为Capture的表单)具有一次性字段。这是说当你处理表单时,你也应该处理BlockingCollection。这是正确的。它无法知道您的应用程序是否会在表单处理后继续运行,因此当您完成表单时,它会唠叨您清理表单及其一次性字段。