C# 如果新项目到达,中断当前项目的处理

C# 如果新项目到达,中断当前项目的处理,c#,wpf,system.reactive,reactive-programming,C#,Wpf,System.reactive,Reactive Programming,我有以下代码: Observable.FromEventPattern<PropertyChangingEventArgs>(_parent, "PropertyChanged") .Subscribe(ep => { switch (ep.EventArgs.PropertyName) { case "Val

我有以下代码:

        Observable.FromEventPattern<PropertyChangingEventArgs>(_parent, "PropertyChanged")
            .Subscribe(ep => 
            {
                switch (ep.EventArgs.PropertyName)
                {
                    case "ValorBlurMenor":
                        LoadBlurMenor();
                        break;
                    case "ValorBlurMaior":
                        LoadBlurMaior();
                        break;
                }
            });
Observable.FromEventPattern(\u parent,“PropertyChanged”)
.订阅(ep=>
{
开关(ep.EventArgs.PropertyName)
{
案例“Valorblumenor”:
LoadBlurMenor();
打破
“ValorBlurMaior”案:
LoadBlurMaior();
打破
}
});
我的问题是,
valorblumenor
valorblumainor
通过WPF滑块进行更改,
loadblumainor()
loadblumenor()
需要一些时间进行评估


我正在寻找一种方法,在新项目到达时中断/取消项目的
Subscribe
委托的执行,因此,始终只对最后一项执行处理。

使其工作的最简单方法是使用
可观察。使用
取消令牌的fromsync
重载,并使用代码中的令牌频繁检查取消:

公共类普通应报告:INotifyPropertyChanged
{
私人厕所需要五秒钟;
私人厕所需要几秒钟;
公共事件属性更改事件处理程序属性更改;
公共图书馆需要五秒钟
{
get=>this.takeFiveSeconds;
设置
{
this.takeFiveSeconds=值;
this.PropertyChanged?.Invoke(this,newpropertyChangedEventArgs(name of(this.TakeFiveSeconds));
}
}
公共图书馆需要几秒钟
{
get=>this.takeTenSeconds;
设置
{
this.takeTenSeconds=值;
this.PropertyChanged?.Invoke(this,newpropertychangedeventargs(name of(this.TakeTenSeconds));
}
}
公共异步任务执行时间(整数秒,CancellationToken=默认值(CancellationToken))
{
Trace.TraceInformation(“开始等待{0}秒”,秒);
等待任务。延迟(秒*1000,令牌);
Trace.TraceInformation(“停止等待{0}秒”,秒);
}
}
公共静态异步无效测试()
{
var测试=新的应纳税义务人();
异步任务属性NameToLongTask(EventPattern参数、CancellationToken标记)
{
开关(args.EventArgs.PropertyName)
{
案例名称(测试时间为5秒):
等待测试。选择某个时间(5,令牌);
打破
案例名称(测试时间为秒):
等待考试。抽空(10,代币);
打破
}
返回单位。默认值;
}
Observable.FromEventPattern(test,nameof(test.PropertyChanged))
.Select(x=>Observable.fromsync(令牌=>propertyNameToLongTask(x,令牌)))
.Switch()
.Subscribe(x=>Trace.TraceInformation(“Beep boop”);
Trace.TraceInformation(“已开始发送通知”);
等待任务。延迟(1000);
test.TakeTenSeconds=true;
等待任务。延迟(2000);
test.TakeFiveSeconds=true;
Trace.TraceInformation(“已完成发送通知”);
}
它给出以下输出:

SandBox.exe Information: 0 : Started sending notifications
SandBox.exe Information: 0 : Started waiting 10 seconds
SandBox.exe Information: 0 : Started waiting 5 seconds
SandBox.exe Information: 0 : Finished sending notifications
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in mscorlib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in mscorlib.dll
SandBox.exe Information: 0 : Stoped waiting 5 seconds
SandBox.exe Information: 0 : Beep boop
重点是:

  • Observable.fromsync()
    :使用正确的
    CancellationToken
    支持创建一个Observable
  • Switch()
    :通过仅订阅最新的可观察对象来进行扁平化,在本例中,它还使用
    CancellationToken

请您澄清一下“
LoadBlurMaior()
LoadBlurMenor()
花点时间评估”的意思好吗?在处理下一个值之前,Rx将始终等待上一个订阅委托完成。因此,除非您的意思是
LoadBlurMaior()
LoadBlurMenor()
触发某种异步行为,否则您的代码应该已经在执行您要求的操作了。@Enigmativity感谢您的关注。当我通过UI滑块更改此viewmodel中的属性时,我开始触发一些由
LoadBlur**()
方法执行的更改。但是,如果在该处理结束之前,我在滑块中再次更改了值,我不想等待上一个处理完成。相反,我希望立即处理最新的数据,丢弃以前数据的部分进度。我猜这或多或少是可以观察到的。Switch
做的。有什么“以前数据的部分进展”呢?Rx从未有过部分进展。是UI取得了部分进展吗?如果是这样,那么这是一个WPF问题,与Rx无关。@Enigmativity抱歉,如果我不清楚的话。假设一个朋友给了我一个桔子,让我把它削皮。我开始剥桔子,但还没等我剥完,他又剥了一个。我所说的“以前数据的部分进展”是指我不再使用的部分剥皮橘子(不是最好的例子,但无论如何)。我的目标是总是立即开始剥最新的橘子,而最好在新的橘子一到就停止剥老的橘子。这和“实时搜索”的例子没什么不同。所以Rx是这样的:假设一个朋友(可观察的)给了我一个橘子(值),并让我剥它(观察者),那么我的朋友会耐心地等待,直到我剥完第一个橘子,然后再告诉我还有另一个橘子(如果有)。