C# 从未显示最后一个值的滑块值更改事件触发任务

C# 从未显示最后一个值的滑块值更改事件触发任务,c#,wpf,multithreading,events,C#,Wpf,Multithreading,Events,我在做图像处理,所以我在一个次级线程上做处理,看起来像这样: 命名空间项目{ 公共类层{ 私有bool applyingActions=false; 公共位图图像{get;set;}; 公共无效应用操作(){ 如果(应用操作)返回; applyingActions=true; Task.Run(()=>{ /*在这里做图像处理*/ 图像=图像结果; applyingActions=false; }); } } } 我用一个和ValueChanged事件触发此线程,如下所示: 命名空间项目{ 公

我在做图像处理,所以我在一个次级线程上做处理,看起来像这样:

命名空间项目{
公共类层{
私有bool applyingActions=false;
公共位图图像{get;set;};
公共无效应用操作(){
如果(应用操作)返回;
applyingActions=true;
Task.Run(()=>{
/*在这里做图像处理*/
图像=图像结果;
applyingActions=false;
});
}
}
}
我用一个和
ValueChanged
事件触发此线程,如下所示:

命名空间项目{
公共部分类主窗口:窗口{
公共层=新层();
公共位图图像显示图像{get{return layer.Image};
公共主窗口(){
DataContext=this;
初始化组件();
}
public void OnValueChanged(对象发送方,事件参数evt){
layer.ApplyActions();
}
}
}
xaml
看起来像这样:


我面临的问题是,当滑块停止移动时,图像不会反映滑块的值,因为当触发最后一个
ValueChanged
事件时,图像仍在处理最后一步

我正在寻找一种方法,使任务进程成为最后一个事件,并忽略从任务开始到最后一个事件之间的事件。要做到这一点,我们可以做些什么

我尝试过使用cancellationtoken,但是,它显示了所有滑块值

命名空间项目{
公共类层{
private CancellationTokenSource cancelSource=新的CancellationTokenSource();
公共位图图像{get;set;};
公共无效应用操作(){
cancelSource.Cancel();
Task.Run(()=>{
/*在这里做图像处理*/
图像=图像结果;
},cancelSource.Token);
}
}
}

从滑块缓存一个值,并在末尾将其与已处理的值进行比较

public class Layer {

    private double _processingValue = -1;
    private bool applyingActions = false;

    public BitmapImage Image { get; set; };

    public void ApplyActions(double value) 
    {
      _processingValue = value;
      if (applyingActions) return;
      applyingActions = true;

      Task.Run(() => {

        /* Do image processing here.... */

        Image = imageResult;

        applyingActions = false;
        
        if(value != _processingValue)
            ApplyActions(_processingValue);

      });
    }
}


private void OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
   layer.ApplyActions(e.NewValue);
}
公共类层{
私有双精度处理值=-1;
私有bool applyingActions=false;
公共位图图像{get;set;};
公共无效应用操作(双值)
{
_处理值=值;
如果(应用操作)返回;
applyingActions=true;
Task.Run(()=>{
/*在这里做图像处理*/
图像=图像结果;
applyingActions=false;
如果(值!=\u处理值)
应用操作(_processingValue);
});
}
}
私有void OnValueChanged(对象发送方,RoutedPropertyChangedEventArgs e)
{
图层应用操作(例如,新值);
}

您是否尝试过使用其他事件处理程序之一?例如,
Drop
是否有效?您需要在此处足够频繁地检查取消令牌:
/*在此处执行图像处理*/。您可以通过调用其
ThrowIfCancellationRequested
方法来检查它。@TheodorZoulias好的,我已经在其中添加了,我将在哪里请求取消?在
任务之前添加它。Run
从不执行该任务。在
应用操作
方法中,您应该做的第一件事是
取消以前的
取消标记源
,然后立即创建新的
取消标记源
,并将其存储在
cancelSource
字段中。这似乎起作用了…您不需要删除它吗?!:)你现在确定它有效,还是仍然怀疑?:)