我对C#的新手很新,我有以下问题:我有一个WPF应用程序,该应用程序执行无限任务,该任务执行了一些非常昂贵的背景操作。这些操作偶尔会改变一个值,并且必须在UI中进行更新。操作需要在与UI线程不同的线程中运行,因为它们可以锁定UI。因此,我正在尝试使用System.Reactive库,并且它实际上运行良好...但是,当我尝试使用执行this.Close();
方法的自定义关闭按钮关闭应用程序时,该应用程序并未关闭。
我的可观察看起来像这样:
internal IObservable<string> DoBackgroundOperations(string param) {
return Observable.Create<string>(o => {
NewThreadScheduler.Default.Schedule(() => {
for (;;) {
param = // some operations that change the param
// when the param has been changed, I send the new value to the subscribers
o.OnNext(param);
}
});
return Disposable.Empty;
});
}
然后我要订阅它,并更改我需要在UI中更新的值:
sevice.DoBackgroundOperations(param).Subscribe(newVal => Data = newVal);
正如我之前说过的,我会收到更新的值来到时运行良好,但是当关闭按钮的点击事件被触发时,UI窗口"消失了"。但是该应用程序本身永远不会关闭。我认为可观察到的线程使应用程序保持活力。
所以,我的问题是:我如何正确关闭该应用程序并防止线程保持其活力?
谢谢!
编辑
我正在使用caliburn.micro来实现MVVM模式。我正在我的一个ViewModel课程中进行订阅。我认为这并不重要,但以防万一...
永远不会返回Disposable.Empty
。您之所以要这样做,是因为您的代码依次没有天然的一次性一次,因为您会创建一个无限的循环。
摆脱无限循环,您可以使整个问题消失。
您可以简单地解决这个问题:
internal IObservable<string> DoBackgroundOperations(string param)
{
return
Observable
.Generate(
0,
x => true,
x => x + 1,
x => /* some operations that change the param */,
Scheduler.Default);
}
我故意选择Scheduler.Default
,因为Scheduler.NewThread
已被弃用。
您是否提供了// some operations that change the param
的代码,我可以给您工作代码。
现在,要干净地关闭您的应用程序,您应该处置您创建的任何订阅,但至少您不再将线程绑在无限循环中。