C# 窗口关闭时线程不终止
我有一个名为C# 窗口关闭时线程不终止,c#,wpf,reflection,C#,Wpf,Reflection,我有一个名为Manager的类,它有一个线程。当应用程序关闭时,我希望找到Manager的所有实例以中止其线程。我该怎么做 我已经在它的UserControl中尝试了unload事件,但它只在UserControl关闭时起作用,而不是整个应用程序 现在我想使用其窗口的Closed事件,但我不想在那里有管理器引用。有什么想法吗?如果您将threads IsBackground属性设置为true,它将不会阻止在退出时终止的应用程序如果您将threads IsBackground属性设置为true,它
Manager
的类,它有一个线程。当应用程序关闭时,我希望找到Manager
的所有实例以中止其线程。我该怎么做
我已经在它的UserControl
中尝试了unload
事件,但它只在UserControl
关闭时起作用,而不是整个应用程序
现在我想使用其
窗口的Closed
事件
,但我不想在那里有管理器
引用。有什么想法吗?如果您将threads IsBackground属性设置为true,它将不会阻止在退出时终止的应用程序如果您将threads IsBackground属性设置为true,它将不会阻止在退出时终止的应用程序将线程设置为后台线程,并在程序结束时自动终止。您可以通过属性设置线程的类型
但是,我不认为这是一个干净的解决方案。使用
while(!terminate){…}
循环更简洁,这样单个线程就可以完成任务,例如写入文件。如果只是终止写入文件的线程,则可能最终导致文件损坏。这不仅适用于文件,也适用于其他项目。将线程设置为后台线程,并在程序结束时自动终止。您可以通过属性设置线程的类型
但是,我不认为这是一个干净的解决方案。使用
while(!terminate){…}
循环更简洁,这样单个线程就可以完成任务,例如写入文件。如果只是终止写入文件的线程,则可能最终导致文件损坏。这不仅适用于文件,也适用于其他项。在Manager类中实现IDisposable
,并确保在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);
}
}
在Manager类中实现
IDisposable
,并确保在Dispose
方法中关闭并取消分配任何资源,例如Threads
。当垃圾收集器在应用程序关闭后开始清理时,将调用此函数,前提是您遵循了正常的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);
}
}
尽管使用IsBackground属性可以工作,但要执行额外的清理,您可以使用Manager类上的一些静态成员跟踪正在运行的线程,并在应用程序退出时循环该集合。尽管使用IsBackground属性可以工作,但要执行额外的清理,您可以使用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));
}
}
请将其他答案和注释作为重构代码并创建另一个解决方案的理由。但是,如果您有某些原因要提交,可以创建一个静态列表,其中包含每个管理器的实例,这些实例可以在退出时中止:
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类是否有对其运行的线程的引用?如果没有,您将如何找到属于管理器的线程?你使用线程池吗?如果是这样,那么管理器可能比线程多。通常:对象在内存中,代码在线程中。他们不需要有任何共同点。
有什么想法吗?
-是的。立即删除所有代码,重新开始,确保遵守关注点分离原则。UI不是“启动线程”的正确位置,UserControl
没有“线程”(不管这意味着什么)。创建适当的ViewModel并管理ViewModel级别所需的任何线程。是的,它有一个参考。我没有使用线程池,因为我的任务需要优先级。@HighCore。我的userControl不知道线程。uc中的某些VM有一个具有线程的管理器。@Bizz在这种情况下,您还应该在ViewModel级别管理这些线程的(优雅)终止,而UI与此无关。请编辑您的问题并添加相关代码,并删除关于UserControl
的部分,如果您处理的是ViewModel,则该部分与问题无关。manager类是否有对其运行线程的引用?如果没有,您将如何找到属于管理器的线程?你使用线程池吗?如果是这样,那么管理器可能比线程多。通常:对象在内存中,代码在线程中。他们不需要有任何共同点。有什么想法吗?
-是的。立即删除所有代码,重新开始,确保遵守关注点分离原则。UI不是“启动线程”的正确位置,UserControl
没有“线程”(不管这意味着什么)。创建适当的ViewModel并管理ViewModel级别所需的任何线程。是的,它有一个参考。我没有使用线程池,因为我的任务需要优先级。@HighCore。我的userControl不知道线程。uc中的某些VM有一个具有线程的管理器。@Bizz在这种情况下,您还应该在ViewModel级别管理这些线程的(优雅)终止,而UI与此无关。请编辑您的问题并添加相关代码,删除关于UserControl
的部分,如果您处理的是ViewModel,则该部分与问题无关。我认为终止此线程不会损坏任何内容。但我记住了这一点。谢谢你提供的信息,我想