Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有IDisposable的自定义初始化函数_C#_.net_Garbage Collection_Idisposable - Fatal编程技术网

C# 具有IDisposable的自定义初始化函数

C# 具有IDisposable的自定义初始化函数,c#,.net,garbage-collection,idisposable,C#,.net,Garbage Collection,Idisposable,在.NET(C#)中,我遵循一些需要构造函数、初始化函数和IDisposable实现的自定义约定和模式。下面举例说明了一个典型的类。没有直接在构造函数中进行初始化,而是通过一个专用函数进行初始化,该函数应该使对象可重用。但是,我不确定调用Dispose时会发生什么。如果GC调用它,对该对象的引用无论如何都会丢失,因此不必担心。如果显式调用它,那么在调用GC.superssFinalize之后,简单地调用Initialize并将该类视为新对象是否有任何缺点?哈哈,我肯定我可以用更简单的方式问这个问

在.NET(C#)中,我遵循一些需要构造函数、初始化函数和IDisposable实现的自定义约定和模式。下面举例说明了一个典型的类。没有直接在构造函数中进行初始化,而是通过一个专用函数进行初始化,该函数应该使对象可重用。但是,我不确定调用Dispose时会发生什么。如果GC调用它,对该对象的引用无论如何都会丢失,因此不必担心。如果显式调用它,那么在调用GC.superssFinalize之后,简单地调用Initialize并将该类视为新对象是否有任何缺点?哈哈,我肯定我可以用更简单的方式问这个问题

public abstract class Thread: System.IDisposable
{

    protected bool Disposed { get; set; }
    protected bool Terminate { get; private set; }
    public bool IsRunning { get; private set; }
    private System.Threading.Thread ThreadObject { get; set; }

    public Thread ()
    {
        this.Initialize();
    }

    ~Thread ()
    {
        this.Dispose(false);
    }

    public virtual void Initialize ()
    {
        this.Stop();

        this.Disposed = false;
        this.Terminate = true;
        this.IsRunning = false;
        this.ThreadObject = null;
    }

    //====================================================================================================
    // Functions: Thread
    //====================================================================================================

    public void Start ()
    {
        if (!this.IsRunning)
        {
            this.IsRunning = true;
            this.Terminate = false;

            this.ThreadObject = new System.Threading.Thread(new System.Threading.ThreadStart(this.Process));
            this.ThreadObject.Start();
        }
    }

    /// <summary>
    /// Override this method to do thread processing.
    /// [this.Terminate] will be set to indicate that Stop has been called.
    /// </summary>
    /// <param name="template"></param>
    protected abstract void Process ();

    public void Stop (System.TimeSpan timeout)
    {
        if (this.IsRunning)
        {
            this.Terminate = true;

            try
            {
                if (timeout.TotalMilliseconds > 1D)
                {
                    this.ThreadObject.Join(timeout);
                }
                else
                {
                    this.ThreadObject.Join();
                }
            }
            catch
            {
                try
                {
                    this.ThreadObject.Abort();
                }
                catch
                {
                }
            }

            this.ThreadObject = null;
            this.IsRunning = false;
        }
    }

    //====================================================================================================
    // Interface Implementation: System.IDisposable
    //====================================================================================================

    public void Dispose ()
    {
        this.Dispose(true);

        System.GC.SuppressFinalize(this);
    }

    protected virtual void Dispose (bool disposing)
    {
        if (!this.Disposed)
        {
            if (disposing)
            {
                // Dispose managed resources.
                this.Stop(System.TimeSpan.FromSeconds(1));
            }

            // Dispose unmanaged resources here.

            // Note disposing has been done.
            this.Disposed = true;
        }
    }

}
公共抽象类线程:System.IDisposable
{
受保护的bool{get;set;}
受保护布尔终止{get;private set;}
公共bool正在运行{get;private set;}
private System.Threading.Thread ThreadObject{get;set;}
公共线程()
{
这是初始化();
}
~Thread()
{
本.处置(假);
}
公共虚拟空间初始化()
{
这个。停止();
这是错误的;
this.Terminate=true;
this.IsRunning=false;
this.ThreadObject=null;
}
//====================================================================================================
//功能:线程
//====================================================================================================
公共无效开始()
{
如果(!this.IsRunning)
{
this.IsRunning=true;
这个。终止=假;
this.ThreadObject=new System.Threading.Thread(new System.Threading.ThreadStart(this.Process));
this.ThreadObject.Start();
}
}
/// 
///重写此方法以执行线程处理。
///[this.Terminate]将被设置为指示已调用Stop。
/// 
/// 
受保护的抽象无效进程();
公共无效停止(System.TimeSpan超时)
{
如果(此.IsRunning)
{
this.Terminate=true;
尝试
{
如果(timeout.total毫秒>1D)
{
this.ThreadObject.Join(超时);
}
其他的
{
this.ThreadObject.Join();
}
}
抓住
{
尝试
{
this.ThreadObject.Abort();
}
抓住
{
}
}
this.ThreadObject=null;
this.IsRunning=false;
}
}
//====================================================================================================
//接口实现:System.IDisposable
//====================================================================================================
公共空间处置()
{
这个。处置(真实);
System.GC.SuppressFinalize(本);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(!this.Disposed)
{
如果(处置)
{
//处置托管资源。
此.Stop(System.TimeSpan.FromSeconds(1));
}
//在此处处置非托管资源。
//注:已完成处理。
这是真的;
}
}
}

GC从不调用
Dispose
,这取决于消费代码。但是,GC确实调用终结器。这在最佳实践
IDisposable
实现中用于仅清理非托管代码

如果在终结器的上下文之外使用Dispose,那么GC就不需要调用终结器,因此
SuppressFinalize
被用作优化,以防止它发生两次


如果重用对象,则会导致问题。从技术上讲,您可以在初始化时重新注册终结器,但这需要确保线程安全。通常的做法是,对象在被
处理后不会被重用,通常
处理方法只能执行一次。在IMO中,初始化方法和对象重用给模式带来了复杂性,使其偏离了预期目的

没有任何技术原因可以解释为什么不能以这种方式重新激活已处置的对象,尽管我不会这样做,因为这违反了最小意外的原则(大多数一次性对象只使用一次)


如果您真的想这样做,我会避免使用终结器,这意味着您的
IDisposable
类不能直接拥有任何非托管资源。您可以通过将类使用的任何非托管资源包装在一个托管包装器中来实现这一点(例如,查看
SafeHandle
类的示例)。

我不喜欢线程处理的所有精确细节,但是如果您将拥有一个类,其中每个实例都拥有一个线程,您应该提供一个Dispose方法,该方法将确保实例的线程以有序的方式消亡

如果您想让线程即使在对象被放弃时也能得到清理,那么您可能必须创建一个外部应用程序持有引用的包装器对象,但您的线程没有。该包装器对象的Finalize()方法应该以使线程消亡的方式推动线程。线程可以简单地每隔几秒钟轮询一个标志,看看它是否应该退出,或者有一个更复杂的终止策略


但是,我很困惑,为什么要初始化调用Stop()?我希望它调用Start()。

代码中使用了错误的语言模式应用程序示例。我清楚地看到C++代码作者的C++背景。遗憾的是C++语言编码技术在C语言中的不适用