我有一个名为Manager
的类,它有一个帖子。当应用程序关闭时,我想找到Manager
的所有实例来中止它们的线程。我怎么能这样做?
我已经在其Unloaded
中尝试了UserControl
事件,但只有当UserControl
关闭而不是整个应用程序时才会有效。
现在我想使用Closed
的{{1}}事件,但我不希望在那里有Window
引用。有什么想法吗?
答案 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