C# - 设计相关的处置问题(取两个)

发布于 2024-08-17 04:17:01 字数 1223 浏览 2 评论 0原文

我今天早些时候问了一个问题,但我认为我需要以不同的方式处理它(最重要的是,关于数据集存在“挂起”)。

下面是一个封装 Font 创建的类(换句话说,它从 xml 文件读取数据,并在运行时根据从该文件读取的内容创建字体):

public class FontCreator
{
    private Font m_TheFont = null;

    public FontCreator( ... some parameters ... )
    {
        m_TheFont = GetTheFont();
    }

    public Font TheFont
    {
        return m_TheFont;
    }

    private Font GetTheFont()
    {
        // code, and more code, that eventually leads to:

        Font f = new Font(fntFamily, fntSize, fntStyle);
        return f;
    }
}

FontCreator 类的使用者看起来有些东西例如:

public class TheConsumer()
{
    private FontCreator m_FontCreator = null;

    public TheConsumer()
    {
        m_FontCreator = new m_FontCreator( ... some parameters ... );
        Initialize();
    }

    private void Initialize()
    {
        InitializeThis();
        InitializeThat();
    }

    private void InitializeThis()
    {
        .... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }

    private void InitializeThat()
    {
        ... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }
}

您添加什么代码以及在哪里添加,以确保显式调用“TheFont”的 Dispose 方法?

I asked a question earlier today, but I think I need to approach it in a different way (on top of that there was a "hang up" in regards to DataSet).

Here's a class that encapsulates the creation of a Font (in other words, it is reading data from an xml file and is creating a font, at runtime, based on what it reads from that file):

public class FontCreator
{
    private Font m_TheFont = null;

    public FontCreator( ... some parameters ... )
    {
        m_TheFont = GetTheFont();
    }

    public Font TheFont
    {
        return m_TheFont;
    }

    private Font GetTheFont()
    {
        // code, and more code, that eventually leads to:

        Font f = new Font(fntFamily, fntSize, fntStyle);
        return f;
    }
}

The consumer of the FontCreator class looks something like:

public class TheConsumer()
{
    private FontCreator m_FontCreator = null;

    public TheConsumer()
    {
        m_FontCreator = new m_FontCreator( ... some parameters ... );
        Initialize();
    }

    private void Initialize()
    {
        InitializeThis();
        InitializeThat();
    }

    private void InitializeThis()
    {
        .... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }

    private void InitializeThat()
    {
        ... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }
}

What code do you add, and where, to ensure that "TheFont"'s Dispose method is explicitly called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

荒路情人 2024-08-24 04:17:01

如果您不希望在初次使用 TheFont 后保留对 TheFont 的引用,请在构造函数中紧随 Initialize 之后调用它的 Dispose 方法。如果您希望让 TheConsumer 保持一段时间并保留对 TheFont 的引用,它会变得更有趣。两个选项:

  1. 您可以从 TheConsumer 对象的析构函数中调用 TheFont 的 dispose 方法。这不是常见做法并且存在问题。主要是,直到垃圾收集发生才调用它。更好的是:
  2. 您可以使 TheConsumer 对象本身实现 IDisposable,并从 TheConsumer.Dispose 调用 TheFont.Dispose。由于 TheConsumer 实现了 IDisposable,因此使用它的代码应该调用它的 Dispose 方法。

编辑以回应严厉的评论!
是的,我应该明确表示除了 2 之外,仅使用 1(如果有的话)。我知道各地的所有开发人员都应该注意到 IDisposable 的实现,但他们常常没有注意到。如果引用的托管资源确实可能保留很长一段时间,并且如果处理不当会导致问题,有时我会在保存引用的对象的析构函数中调用安全 Dispose() 方法。这有那么错吗? :)

If you don't wish to maintain a reference to TheFont after it is initially used, then call it's Dispose method in your constructor, right after Initialize. If you wish to keep TheConsumer alive for a while and maintain a reference to TheFont, it gets more interesting. Two Options:

  1. You can have TheFont's dispose method called from the Destructor of the TheConsumer object. This is not the common practice and has problems. Mainly, this is not called until garbage collection happens. Better is:
  2. You can make the TheConsumer object itself implement IDisposable, and call TheFont.Dispose from TheConsumer.Dispose. Since TheConsumer implements IDisposable, the code that uses it should call its Dispose method.

Edit in response to harsh comment!
Yes, I should have made clear to only use 1 in addition to 2, if at all. I know all developers everywhere are supposed to notice when IDisposable is implemented, but they often don't. If the referenced managed resource might really remain around a long time and cause problems if not properly disposed, I sometimes have a safety Dispose() method call in the destructor of the object holding the reference. Is that so wrong? :)

好倦 2024-08-24 04:17:01
public TheConsumer()
{
    using (m_FontCreator = new m_FontCreator( ... some parameters ... ))
    {
        Initialize();
    }
}
public TheConsumer()
{
    using (m_FontCreator = new m_FontCreator( ... some parameters ... ))
    {
        Initialize();
    }
}
苹果你个爱泡泡 2024-08-24 04:17:01

我很困惑,如果您想快速使用字体创建器对象,请在 FontCreater 上实现 IDisposable 并使用

using(m_FontCreator = new FontCreater(....))
{
   InitializeThis();
   InitializeThat();
}

如果您需要保留 FontCreater< 的实例/code> 贯穿 TheConsumer 的生命周期,然后FontCreaterTheConsumer上实现 IDisposable代码>类。

public class TheConsumer : IDisposable
{
  void Dispose()
  {
     if(m_FontCreator != null)
          m_FontCreator.Dispose();
  }
}

然后像这样使用 TheConsumer

using(TheConsumer consumer = new TheConsumer(....))
{
  ....
}

I am confused, if you want to quickly use the font creater object then implement IDisposable on the FontCreater and use

using(m_FontCreator = new FontCreater(....))
{
   InitializeThis();
   InitializeThat();
}

If you need to keep the instance of the FontCreater through the lifetime of TheConsumer, then implement IDisposable on both FontCreater and TheConsumer classes.

public class TheConsumer : IDisposable
{
  void Dispose()
  {
     if(m_FontCreator != null)
          m_FontCreator.Dispose();
  }
}

then use TheConsumer class like so

using(TheConsumer consumer = new TheConsumer(....))
{
  ....
}
倚栏听风 2024-08-24 04:17:01

答案1:避免它。不要将包含非托管资源的对象保留的时间超过必要的时间。

答案 2:如果您确实需要代码中所示的嵌入字段,则 FontCreator 和 Consumer 类都需要实现 IDisposable。但不是析构函数(Finalizer)。
对此的主要论点是 FontCreator 是字体的“所有者”,因此应该承担责任。消费者也同样对创造者负责。

正如其他人所指出的,看来您至少可以避免 Consumer 类中的 m_FontCreator 字段。但这取决于其余的代码,m_FontCreator是否在其他地方使用?

Answer 1: Avoid it. Don't keep objectsthat contain unmanaged resources around any longer than necessary.

Answer 2: If you do need the embedded fields as shown in your code, than both the FontCreator and the Consumer class need to implement IDisposable. But not a destructor (Finalizer).
The main argument for this is that FontCreator is the 'owner' of the Font and should therefore take responsibility. And the Consumer is responsible for the Creator in the same way.

As others have noted, it appears you can at least avoid the m_FontCreator field in the Consumer class. But it depends on the rest of the code, is m_FontCreator used elsewhere?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文