相关疑难解决方法(0)

正确使用IDisposable接口

我从阅读MSDN文档中了解到,IDisposable接口的"主要"用途是清理非托管资源.

对我来说,"非托管"意味着数据库连接,套接字,窗口句柄等等.但是,我已经看到了Dispose()实现该方法以释放托管资源的代码,这对我来说似乎是多余的,因为垃圾收集器应该照顾那对你而言.

例如:

public class MyCollection : IDisposable
{
    private List<String> _theList = new List<String>();
    private Dictionary<String, Point> _theDict = new Dictionary<String, Point>();

    // Die, clear it up! (free unmanaged resources)
    public void Dispose()
    {
        _theList.clear();
        _theDict.clear();
        _theList = null;
        _theDict = null;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是否使得垃圾收集器可以使用的内存MyCollection比通常更快?

编辑:到目前为止,人们已经发布了一些使用IDisposable清理非托管资源(例如数据库连接和位图)的好例子.但是假设_theList在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?

.net c# garbage-collection idisposable

1586
推荐指数
12
解决办法
31万
查看次数

正确实现IDisposable

在我的类中,我实现IDisposable如下:

public class User : IDisposable
{
    public int id { get; protected set; }
    public string name { get; protected set; }
    public string pass { get; protected set; }

    public User(int UserID)
    {
        id = UserID;
    }
    public User(string Username, string Password)
    {
        name = Username;
        pass = Password;
    }

    // Other functions go here...

    public void Dispose()
    {
        // Clear all property values that maybe have been set
        // when the class was instantiated
        id = 0; …
Run Code Online (Sandbox Code Playgroud)

.net c# garbage-collection memory-leaks memory-management

132
推荐指数
6
解决办法
10万
查看次数

是否滥用IDisposable和"使用"作为获取异常安全的"范围行为"的手段?

我经常在C++中使用的东西是让一个类通过构造函数和析构函数A处理另一个类的状态入口和退出条件,以确保如果该范围内的某些东西抛出异常,那么B将具有已知状态范围已退出.就首字母缩略词而言,这不是纯粹的RAII,但它仍然是一种既定的模式.BA

在C#中,我经常想做

class FrobbleManager
{
    ...

    private void FiddleTheFrobble()
    {
        this.Frobble.Unlock();
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

这需要像这样做

private void FiddleTheFrobble()
{
    this.Frobble.Unlock();

    try
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
    }
    finally
    {
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想保证退货Frobble时的状态FiddleTheFrobble.代码会更好

private void FiddleTheFrobble()
{
    using (var janitor = new FrobbleJanitor(this.Frobble))
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling raii

107
推荐指数
6
解决办法
6151
查看次数

.NET中"托管"与"非托管"资源的含义是什么?

.NET中托管资源和非托管资源的含义是什么意思?他们是如何进入画面的?

.net c# unmanaged managed

103
推荐指数
4
解决办法
5万
查看次数

IntPtr,SafeHandle和HandleRef - 解释

在没有指向MSDN的情况下,有人可以简明扼要地解释每个问题的目的以及何时使用它们.(IntPtr,SafeHandle和HandleRef)

.net winapi interop

39
推荐指数
2
解决办法
2万
查看次数

处理,何时被称为?

请考虑以下代码:

namespace DisposeTest
{
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Calling Test");

            Test();

            Console.WriteLine("Call to Test done");
        }

        static void Test()
        {
            DisposeImplementation di = new DisposeImplementation();
        }
    }

    internal class DisposeImplementation : IDisposable
    {
        ~DisposeImplementation()
        {
            Console.WriteLine("~ in DisposeImplementation instance called");
        }
        public void Dispose()
        {
            Console.WriteLine("Dispose in DisposeImplementation instance called");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

即使我在Test();调用之后放置了一个等待循环,Dispose也永远不会被调用.所以这很糟糕.我想编写一个简单易用的类,以确保清理所有可能的资源.我不想把这个责任交给我班级的用户.

可能的解决方案:使用using或调用自己处理(基本相同).我可以强制用户使用吗?或者我可以强制调用处理吗?

呼叫GC.Collect();Test();也不起作用.

dinull不调用任何处置.解构器可以工作,因此对象在退出时会被解构Test()

好的,现在很清楚!

谢谢大家的答案!我会在评论中添加警告!

.net c# garbage-collection dispose idisposable

29
推荐指数
4
解决办法
4万
查看次数

我什么时候应该在.NET中处理我的对象?

对于一般代码,我真的需要处理一个对象吗?我可以在大多数情况下忽略它,或者当你100%确定你不再需要它时总是丢弃一个物体是个好主意吗?

.net garbage-collection dispose

18
推荐指数
3
解决办法
1万
查看次数

什么时候需要处理?

当你有像这样的代码:

Bitmap bmp = new Bitmap ( 100, 100 );
Graphics g = Graphics.FromImage ( bmp );

Pen p = new Pen ( Color.FromArgb ( 128, Color.Blue ), 1 );
Brush b = new SolidBrush ( Color.FromArgb ( 128, Color.Blue ) );

g.FillEllipse ( b, 0, 0, 99, 99 );    
g.FillRegion ( b, pictureBox1.Region );

pictureBox1.BackColor = Color.Transparent;
pictureBox1.Image = bmp;
Run Code Online (Sandbox Code Playgroud)

你必须丢弃笔和刷子吗?那么bmp和g呢?

我的主要问题是,如果要手动处理这些问题,为什么他们一旦离开范围就不会被处置?如果您没有手动处理它们会发生什么?这是人们手动执行此操作的延迟吗?

.net c# gdi+ garbage-collection dispose

13
推荐指数
3
解决办法
8578
查看次数

只要有相应的"开始"呼叫,就执行"结束"呼叫

假设我想强制执行一条规则:

每次在函数中调用"StartJumping()"时,必须在返回之前调用"EndJumping()".

当开发人员编写代码时,他们可能只是忘记调用EndSomething - 所以我想让它易于记忆.

我只能想到一种方法:它滥用"using"关键字:

class Jumper : IDisposable {
    public Jumper() {   Jumper.StartJumping(); }
    public void Dispose() {  Jumper.EndJumping(); }

    public static void StartJumping() {...}
    public static void EndJumping() {...}
}

public bool SomeFunction() {
    // do some stuff

    // start jumping...
    using(new Jumper()) {
        // do more stuff
        // while jumping

    }  // end jumping
}
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

c# business-logic

8
推荐指数
5
解决办法
754
查看次数