2

我创建了一个从 Component 派生的类:

public class MyComponent: System.ComponentModel.Component
{


}

我看到 Visual Studio 为我放入了这段代码:

protected override void Dispose(bool disposing)
{
    try
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
    }
    catch
    {
        throw;
    }
    finally
    {
        base.Dispose(disposing);
    }
}

MyComponent有一个成员是 a DataSet,也许还有其他一些成员实现IDisposable. 如果有的话,我需要用Dispose()方法修改什么以确保正确清理东西?感谢您的帮助。

4

4 回答 4

2

改变:

if (disposing && (components != null))
{
     components.Dispose();
}

成为:

if (disposing && (components != null))
{
    _dataset.Dispose();
    components.Dispose();
}
于 2008-10-30T15:13:32.787 回答
0

检查任何一次性成员对象,如果它们不为空,则将它们处理掉。

于 2008-10-30T15:15:13.267 回答
0

我想出了这门课:

public class DisposableComponentWrapper : IComponent
{
    private IDisposable disposable;

    public DisposableComponentWrapper(IDisposable disposable)
    {
        this.disposable = disposable;
    }

    public DisposableComponentWrapper(IDisposable disposable, ISite site)
        : this(disposable)
    {
        Site = site;
    }

    public void Dispose()
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }
        if (Disposed != null)
        {
            Disposed(this, EventArgs.Empty);
        }
    }

    public ISite Site { get; set; }

    public event EventHandler Disposed;
}

和 IContainer 的扩展方法:

public static void Add(this IContainer container, IDisposable disposableComponent)
{
    var component = (disposableComponent as IComponent);
    if(component == null)
    {
        component = new DisposableComponentWrapper(disposableComponent);
    }
    container.Add(component);
}

这可能会帮助那些愿意为他们的表格争取可支配资源的人。

注意:我不确定 IComponent.Disposed 的行为,MSDN并没有说明在此接口的实现中应该如何调用它,文档听起来像是在谈论注册到事件的客户端代码而不是应该何时由该接口的实现触发。

于 2012-02-07T00:45:18.527 回答
-1

将一次性用品包装在组件中并将它们添加到components集合中。dispose 模式的生成实现将正确地处理它们。

public partial class MyComponent : System.ComponentModel.Component
{
    private readonly System.Data.DataSet _dataSet;

    public MyComponent(System.Data.DataSet dataSet)
    {
        _dataSet = dataSet ?? throw new System.ArgumentNullException(nameof(dataSet));
        components.Add(new DisposableWrapperComponent(dataSet));
    }
}

是这样定义的DisposableWrapperComponent

using System;
using System.ComponentModel;

public class DisposableWrapperComponent : Component
{
    private bool disposed;

    public IDisposable Disposable { get; }

    public DisposableWrapperComponent(IDisposable disposable)
    {
        Disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));
    }

    protected override void Dispose(bool disposing)
    {
        if (disposed) return;

        if (disposing)
        {
            Disposable.Dispose();
        }

        base.Dispose(disposing);

        disposed = true;
    }
}

@smoothdeveloper回答的启发。

如果您需要能够重置数据集,则将生命周期管理封装在属性中效果很好。

using System;
using System.ComponentModel;
using System.Data;

public partial class MyComponent : Component
{
    private const string DataSetComponentName = "dataSet";

    public DataSet DataSet
    {
        get => (DataSet)((DisposableWrapperComponent)components.Components[DataSetComponentName])
                ?.Disposable;
        set
        {
            var lastWrapper = (DisposableWrapperComponent)components.Components[DataSetComponentName];
            if (lastWrapper != null)
            {
                components.Remove(lastWrapper);
                lastWrapper.Dispose();
            }

            if (value != null)
            {
                components.Add(new DisposableWrapperComponent(value), DataSetComponentName);
            }
        }
    }

    public MyComponent(DataSet dataSet)
    {
        DataSet = dataSet ?? throw new ArgumentNullException(nameof(dataSet));
    }
}

我在实现一个 Windows 服务时使用了OnStart它,该服务在OnStop.

于 2019-12-17T21:19:29.120 回答