假设以下情况: 在MVVM实现中有一个WPF窗口。在其后面的代码中包含代码(实际上我知道我应该首先使用ViewModel方法,但在此阶段使用View First就足够了):
public MainWindow()
{
InitializeComponent();
this.DataContext = MainWindowViewModel.GetInstance();
}
的构造函数中的
ClassStartingWorkerThread instance;
MainWindowViewModel()
{
instance = new ClassStartingWorkerThread();
}
我初始化一个类的实例,它在构造时启动一个Thread,如下所示:
ClassStartingWorkerThread()
{
StartThread();
}
private Thread mEventRequestingThread = null;
private void StartThread()
{
ThreadStart cDelegate = new ThreadStart(EventListening);
mEventRequestingThread = new Thread(cDelegate);
mEventRequestingThread.Start();
}
此类实现IDisposable接口。 因此,我在Destruction上手动调用我的Dispose方法,如下所示:
~ClassStartingWorkerThread()
{
Dispose(false);
}
public void Dispose()
{
mEventRequestingThread.Abort();
}
至少你应该知道:我从Visual Studio开始我的应用程序。 现在,我正在关闭我的UI窗口,并希望我的例程能够破坏创建的对象。 但Visual Studio不会返回“编辑”模式并保持“调试”模式。
我想我的线程例程有问题,但我想知道为什么MainWindow析构函数和MainWindowViewModel析构函数都没有被调用。
这导致了一个问题,即如何手动启动销毁例程并告诉我的工作线程(实际上似乎阻止了这个)停止了?
提前致谢, 托马斯
答案 0 :(得分:3)
问题是你的析构函数~ClassStartingWorkerThread()
永远不会被垃圾收集器调用。由于执行线程通过ThreadStart委托引用它,因此无法对该类的实例进行垃圾收集。一般来说,你永远不应该依赖于一个完全被召唤的破坏者。请参阅C# Destructors上的MSDN。
在您的情况下,只需将Thread.IsBackground属性设置为true
即可。这将使应用程序关闭时线程自动终止。
如果你真的必须手动控制你的工作线程的终止,你不应该中止它,而是让它等待(或循环检查)一些WaitHandle并在WaitHandle是信号。当涉及终止时,Set主线程中的WaitHandle,可能在Window.Closing
事件处理程序中。
答案 1 :(得分:1)
我同意克莱门斯的回答。
只有两点:
在closewindow事件中删除您的主题。我不知道WPF中事件的名称,但必须有一个在关闭窗口时调用。使用它。
删除线程时,您应该总是更喜欢Abort()之外的其他一些方法。向该线程发送一个信号,让它被告知窗口即将关闭,让线程和平地自行结束执行。