C#队列最新异步任务
我正在处理一个WPF应用程序,在该应用程序中,只要数据绑定到滑块的属性发生更改,我就需要执行冗长的操作。有没有简单的方法来为这个操作排队异步任务,但确保只有最近排队的任务运行?C#队列最新异步任务
我设法创建一个使用Task.ContinueWith()
一个任务链来解决我的问题。线程安全计数器确保只有链中的最后一个任务实际运行。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace WpfApp1
{
public class AsyncTaskRunner
{
#region Member Variables
Task m_TaskChain;
int m_TaskCount;
#endregion
#region Constructors
public AsyncTaskRunner()
{
//Initialize the member variables
m_TaskChain = Task.CompletedTask;
m_TaskCount = 0;
}
#endregion
#region Public Methods
public void Run(Action action)
{
//Add a continuation to the task chain using the specified action
Interlocked.Increment(ref m_TaskCount);
m_TaskChain = m_TaskChain.ContinueWith((prevTask) =>
{
//Call the action if we're the last task in the task chain
if (Interlocked.Decrement(ref m_TaskCount) == 0)
{
action();
}
});
}
public async Task WaitAsync()
{
//Wait for the asynchronous task chain to finish
await m_TaskChain;
}
#endregion
}
}
您可以使用单个任务,取消它,然后重新分配一个新任务。该任务可以用延迟被链接去抖滑块:
CancellationTokenSource cancel;
Task task;
...
cancel?.Cancel();
cancel?.Dispose();
cancel = new CancellationTokenSource();
task = Task.Delay(3000, cancel.Token).ContinueWith(...);
在这种情况下,冗长的任务是将数据推送到设备,因此取消它会产生令人讨厌的副作用 –
@ NeilThiessen我编辑了我的答案,因此它只取消延迟任务。 – mtman
您也可以延迟更新o f绑定,通过添加一个['Delay'](https://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.delay%28v=vs.110%29.aspx?f = 255&MSPPError = -2147217396)。这对于可以快速更改其值的属性非常有用。延迟计时器从第一次更新开始,但只会在计时器结束后实际更新支持属性,但会以*最新*值进行更新。您可以像这样使用它'
您可以将Delay
添加到行这Binding
。
MSDN特别提出Slider
作为一个很好的候选人使用它:
如果使用数据绑定来更新数据源,可以使用 延迟属性指定的时间量来传递在源更新之前在目标上更改属性 之后。例如,假设 您有一个Slider,它的Value属性数据双向绑定到 到数据对象的属性,并且UpdateSourceTrigger属性是 设置为PropertyChanged。在这个例子中,当用户移动Slider时,Slider移动的每个像素的源更新。只有当 滑块的值停止更改时,源对象通常才需要滑块的值。为了防止经常更新源 ,使用延迟指定不应更新源 ,直到拇指停止移动后经过一段时间。
它可以像这样使用:
<TextBlock Text="{Binding Name, Delay=500}"/>
我需要长时间运行的任务,以便在滑块变化时尽可能快地运行。 '延迟'只是防止绑定更新,直到滑块停止移动... –
你问如何为*油门*事件由滑块解雇?这与排队不同。 .NET的机制允许你排列数据进行处理([ActionBlock](https://msdn.microsoft.com/en-us/library/hh194684(v = vs.110).aspx)),只保留一个([BroadcastBlock ](https://msdn.microsoft.com/en-us/library/hh160447(v = vs.110).aspx)或限制事件流,因此每X或T只有一个事件秒通过[Observable.Throttle](https://msdn.microsoft.com/en-us/library/hh229400(v = vs.103).aspx)。这些*不同。我会说你想节流 –
节流确实听起来像是一个很好的解决方案,你能提供一个我将如何实现的例子吗? –