何时处理对象?C#

3
我写了一个for循环,在其中声明了一个新的Image,那么我应该在内部的每个for循环中都Dispose它,还是在全部完成后Dispose它,有什么区别?
以下是一个示例以更清楚地说明这一点, 我应该使用以下方式:
for (int i = 0; i < 10; i++)
{
    Image imgInput = new Image();

    for (int j = 0; j < 100; j++)
    {
        // Here is a code to use my image

        Image.Dispose();
    }
}

或者:

for (int i = 0; i < 10; i++)
{
    Image imgInput = new Image();

    for (int j = 0; j < 100; j++)
    {
        // Here is a code to use my image
    }

    Image.Dispose();
}

3
我认为你需要展示一些代码并描述你想让代码做什么。 - Connell.O'Donnell
2个回答

6

通常我们会使用usingIDisposable包装起来,以确保实例(即非托管资源)可以被“雨或风”地处理。如果你想在内部循环之外声明Image

for (int i = 0; i < 10; i++)
{
    using (Image imgInput = new Image()) 
    {
        for (int j = 0; j < 100; j++)
        {
            ...
            // In all these cases the resource will be correctly released: 

            if (someCondition1) 
                break;

            ...

            if (someCondition2) 
                return;

            ...

            if (someCondition3) 
                throw new SomeException(...);

            ...  
            // Here is a code to use my image
        }
    }
}

这就是为什么我们不应该显式调用Dispose。请注意,在出现someCondition2someCondition3的情况下,您所提供的两个代码片段都会导致资源泄漏

如果您想在嵌套循环内声明Image,则使用相同的方法:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 100; j++) 
    {
        using (Image imgInput = new Image()) 
        {
            // Here is a code to use my image
        }        
    }     
}

2
如果您不调用dispose方法,则析构函数(finalizer)将负责释放资源。GC仅清理托管资源。调用Bitmap.Dispose可确保及时清理这些非托管资源,以避免资源泄漏。
通常情况下,在您的情况下,如果超出范围,则会调用析构函数。

始终在释放对图像的最后引用之前调用Dispose。否则,它正在使用的资源将不会被释放,直到垃圾回收器调用Image对象的Finalize方法。

您的第二种方法很有道理。在使用图像对象后,您将dispose它。
for (int i=0;i<10;i++)
{
    Image imgInput = new Image();
    for (int j=0;j<100;j++)
    {
        //Here is a code to use my image
    }
    Image.Dispose();
}

当您使用完图像后,请调用Dispose。Dispose方法将使图像处于不可用状态。在调用Dispose之后,必须释放对图像的所有引用,以便垃圾收集器可以回收图像占用的内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接