窗口关闭时,线程不会终止

时间:2014-05-12 14:43:28

标签: c# wpf reflection

我有一个名为Manager的类,它有一个帖子。当应用程序关闭时,我想找到Manager的所有实例来中止它们的线程。我怎么能这样做?

我已经在其Unloaded中尝试了UserControl事件,但只有当UserControl关闭而不是整个应用程序时才会有效。

现在我想使用Closed的{​​{1}}事件,但我不希望在那里有Window引用。有什么想法吗?

5 个答案:

答案 0 :(得分:2)

如果将线程IsBackground属性设置为true,它将不会阻止应用程序在退出时终止

答案 1 :(得分:2)

使线程成为后台线程,并在程序结束时自动终止。您可以通过IsBackground属性设置线程类型。

但是,我不认为这是一个干净的解决方案。使用while(!terminate) { ... }循环更简洁,以便单个线程可以完成其任务,例如写入文件。如果您只是终止写入文件的线程,您可能最终会损坏文件。这不仅适用于文件,也适用于其他项目。

答案 2 :(得分:2)

在您的Manager类中实施IDisposable,并确保在Threads方法中关闭和取消分配任何资源,例如Dispose。如果您已经按照此处的正常IDisposable模式执行了垃圾收集器在应用程序关闭后进行清理,则会调用此方法:

public class ComplexResourceHolder : IDisposable {

    private IntPtr buffer; // unmanaged memory buffer
    private SafeHandle resource; // disposable handle to a resource

    public ComplexResourceHolder(){
        this.buffer = ... // allocates memory
        this.resource = ... // allocates the resource
    }

    protected virtual void Dispose(bool disposing){
            ReleaseBuffer(buffer); // release unmanaged memory
        if (disposing){ // release other disposable objects
            if (resource!= null) resource.Dispose();
        }
    }

    ~ ComplexResourceHolder(){
        Dispose(false);
    }

    public void Dispose(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

答案 3 :(得分:1)

虽然使用IsBackground属性可以工作,但是为了执行额外的清理,您可以使用Manager类上的一些静态成员来跟踪正在运行的线程,并在应用程序退出时循环该集合。

答案 4 :(得分:1)

请将其他答案和评论作为重构代码并创建其他解决方案的理由。但是,如果您有理由提交此操作,则可以创建一个静态列表,其中包含可在退出时中止的每个Manager的实例:

class Manager
{
    //A WeakReference prevents memory leaks when you dispose of managers in another place
    private static readonly List<WeakReference<Manager>> Instances 
             = new List<WeakReference<Manager>>();

    public static void AbortAll()
    {
        foreach (var weakReference in Instances)
        {
            Manager current;
            if (weakReference.TryGetTarget(out current))
                current.Abort();
        }
        Instances.Clear();
    }

    private void Abort()
    {
        //...
    }

    public Manager()
    {
        //...
        Instances.Add(new WeakReference<Manager>(this));
    }
}

用法:

Manager a = new Manager();
Manager b = new Manager();

Manager.AbortAll(); //calls abort on a and b