关闭WPF窗口不会启动销毁

时间:2012-01-31 11:38:32

标签: c# .net wpf mvvm

假设以下情况: 在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析构函数都没有被调用。

这导致了一个问题,即如何手动启动销毁例程并告诉我的工作线程(实际上似乎阻止了这个)停止了?

提前致谢, 托马斯

2 个答案:

答案 0 :(得分:3)

问题是你的析构函数~ClassStartingWorkerThread()永远不会被垃圾收集器调用。由于执行线程通过ThreadStart委托引用它,因此无法对该类的实例进行垃圾收集。一般来说,你永远不应该依赖于一个完全被召唤的破坏者。请参阅C# Destructors上的MSDN。

在您的情况下,只需将Thread.IsBackground属性设置为true即可。这将使应用程序关闭时线程自动终止。

如果你真的必须手动控制你的工作线程的终止,你不应该中止它,而是让它等待(或循环检查)一些WaitHandle并在WaitHandle是信号。当涉及终止时,Set主线程中的WaitHandle,可能在Window.Closing事件处理程序中。

答案 1 :(得分:1)

我同意克莱门斯的回答。

只有两点:

  1. 在closewindow事件中删除您的主题。我不知道WPF中事件的名称,但必须有一个在关闭窗口时调用。使用它。

  2. 删除线程时,您应该总是更喜欢Abort()之外的其他一些方法。向该线程发送一个信号,让它被告知窗口即将关闭,让线程和平地自行结束执行。