【问题标题】:How to detect nullification of an object from a working thread inside it如何从对象内部的工作线程中检测对象的无效化
【发布时间】:2016-10-02 22:09:09
【问题描述】:

我正在开发一个 ReloadableCollection,它每秒在其中的后台线程上重新加载一次。问题是当我使集合的一个实例无效时,线程并没有停止(因为它不知道它正在工作的实例已被无效)。

我尝试了多种方法,例如对实例使用包装器,使 ThreadWork 方法静态并在启动时为其提供实例 (start(this)),在 Collection 的析构函数中将取消设置为 false,... 没有工作。

可以在下面的代码中看到问题的示例。

我的收藏类:

class Collection
{
    private const int INTERVAL=1000;

    Thread thread;

    public Collection()
    {
        thread=new Thread(ThreadWork);
        thread.Start();
    }

    private void ThreadWork()
    {
        while(true){ // how to detect when the instance is nullified?
            Reload();
            Thread.Sleep(INTERVAL);
        }
    }

    private void Reload()
    {
        // reload the items if there are any changes
    }
}

示例用法:

void Main()
{
    Collection myCollection=new Collection();

    // ...
    // here, it is reloading, like it should be
    // ...

    myCollection=null;

    // ...
    // here, it should not be reloading anymore, but the thread is still running and therefore "reloading"
}

【问题讨论】:

    标签: c# multithreading garbage-collection pass-by-reference instances


    【解决方案1】:

    编写一个显式的“停止”方法。不要通过将变量或字段设置为 null 来触发行为。

    这里发生了什么?

    Collection myCollection = new Collection();
    var myOtherCollection = myCollection;
    myCollection = null; //Should it stop here?
    myOtherCollection = null; //And now? Both are null.
    
    Collection myCollection = new Collection();
    MyMethod(myCollection);
    myCollection = null; //And here? What if MyMethod adds the collection to a list, or keeps track of it?
    
    void Test()
    {
        Collection myCollection = new Collection();
    } //Should it stop reloading when we exit the method?
    

    只需告诉集合在您完成后停止重新加载。我保证,你会避免更多的头痛。

    private volatile bool _stopping;
    private void ThreadWork()
    {
        while (!_stopping)
        {
            Reload();
            Thread.Sleep(INTERVAL);
        }
    }
    
    public void Stop()
    {
        _stopping = true;
    }
    

    【讨论】:

    • 或者实际上,让它实现 IDisposable,因为这是一个可以置于不再使用状态的类的 .NET 习惯用法。
    • @JonHanna 是的,这也有效。虽然原则仍然存在:我们需要明确说我们什么时候完成
    • IDisposable 的优势在于它可以将其标记给用户,并允许方便的using 机制。
    • 谢谢你的解释,我实现了IDisposable并解决了问题。
    猜你喜欢
    • 2021-04-29
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多