gpt4 book ai didi

c# - 为什么这个 Cancellation Disposable 永远不会在 Observable.Dispose() 上被取消?

转载 作者:可可西里 更新时间:2023-11-01 10:01:01 29 4
gpt4 key购买 nike

我在 WinForms 应用程序中使用 RxFramework。我正在尝试运行 Observable 异步并使用 CancellationDisposable 在用户单击按钮时取消操作。但它不工作!

假设我有一个带有 2 个按钮和一个 ProgressBar 的表单。 Button1_click 在新线程上订阅观察者。然后在取消操作后立即按下 Button2_click。为什么 cancel.Token.IsCancellationRequested 永远不会为真?

private IDisposable obs = null;
private void button1_Click(object sender, EventArgs e) {
var countObserver = Observable.Create<int>(observer => {
var cancel = new CancellationDisposable();

if (!cancel.Token.IsCancellationRequested) {
//Step 1 of a long running process using lot of resources...
observer.OnNext(1);
}
if (!cancel.Token.IsCancellationRequested) {
//Step 2 of a long running process using lot of resources...
observer.OnNext(1);
}
if (!cancel.Token.IsCancellationRequested) {
//Step 3 of a long running process using lot of resources...
observer.OnNext(1);
}
observer.OnCompleted();

return cancel;
});

obs = countObserver
.ObserveOn(new ControlScheduler(this))
.SubscribeOn(Scheduler.ThreadPool)
.Subscribe(i => {
//Update a progress bar here...
});

}

private void button2_Click(object sender, EventArgs e) {
if (obs != null)
obs.Dispose();
}

最佳答案

之所以会这样,是因为您传递给 Observable.Create 的 lambda 不会返回 CancellationDisposable 直到它完成所有步骤。因此,操作顺序如下:

  1. 您调用订阅
  2. UI线程 block
  3. ThreadPool线程上,执行进入lambda
  4. CancellationDisposable 已创建
  5. 您多次检查取消并执行整个过程。在此期间,您的进度条会更新。
  6. cancel 从 lambda 返回
  7. UI线程被释放,obs得到它的值
  8. 您点击 Button2 并调用 obs.Dispose
  9. cancel 获取 cancel.Token.IsCancellationRequested=true。但是什么都没有发生,因为一切都已经发生了。

固定代码如下:

private void button1_Click(object sender, EventArgs e) {
var countObserver = Observable.Create<int>(observer => {
var cancel = new CancellationDisposable();

// Here's the magic: schedule the job in background and return quickly
var scheduledItem = Scheduler.ThreadPool.Schedule(() =>
{
if (!cancel.Token.IsCancellationRequested) {
//Step 1 of a long running process using lot of resources...
observer.OnNext(1);
}
if (!cancel.Token.IsCancellationRequested) {
//Step 2 of a long running process using lot of resources...
observer.OnNext(1);
}
if (!cancel.Token.IsCancellationRequested) {
//Step 3 of a long running process using lot of resources...
observer.OnNext(1);
}
observer.OnCompleted();
});

return new CompositeDisposable(cancel, scheduledItem);
});

obs = countObserver
.ObserveOn(new ControlScheduler(this))
.Subscribe(i => {
//Update a progress bar here...
});

}

关于c# - 为什么这个 Cancellation Disposable 永远不会在 Observable.Dispose() 上被取消?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8172235/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com