C# 如何分派由特定事件创建的每个以前的任务
我的WPF.NET4.5应用程序中有一个事件,每秒最多可以触发10次,该事件正在计算不需要的数据,因此我正在寻找一种方法来消除不必要的计算压力,并在事件未触发3秒时调用该方法。我考虑过使用C# 如何分派由特定事件创建的每个以前的任务,c#,asynchronous,C#,Asynchronous,我的WPF.NET4.5应用程序中有一个事件,每秒最多可以触发10次,该事件正在计算不需要的数据,因此我正在寻找一种方法来消除不必要的计算压力,并在事件未触发3秒时调用该方法。我考虑过使用async这样的功能: private async Task DoWork() { await Task.Delay(3000); ... } private void Event() { Task.Run(() => DoWork()); } 我真的不确定如何优雅地处理不需要
async
这样的功能:
private async Task DoWork()
{
await Task.Delay(3000);
...
}
private void Event()
{
Task.Run(() => DoWork());
}
我真的不确定如何优雅地处理不需要的
任务
,即当用户触发事件时,由该事件创建的每个任务都应该终止,并且应该尽可能快。我尝试过使用CancellationToken
,但我不确定这是否适合我的情况您可以使用CancellationTokenSource
让任务中的代码知道它已被取消:
private CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource ();
让我们改变一下:
private async Task DoWork()
{
await Task.Delay(3000);
...
}
致:
现在,如果需要,我们可以取消任务:
CancellationTokenSource.Cancel();
Task.Delay
将观察CancellationToken,如果它处于已取消状态,它将中止任务执行。稍后在代码中,我们将检查是否需要执行任何操作。您可以使用CancellationTokenSource
让任务中的代码知道它已被取消:
private CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource ();
让我们改变一下:
private async Task DoWork()
{
await Task.Delay(3000);
...
}
致:
现在,如果需要,我们可以取消任务:
CancellationTokenSource.Cancel();
Task.Delay
将观察CancellationToken,如果它处于已取消状态,它将中止任务执行。稍后在代码中,我们检查是否需要执行任何操作。这是我基于@Fabjan answer的解决方案
private static void RunSingleTask(ref CancellationTokenSource cts, int delay, Action func)
{
if (cts != null)
{
cts.Cancel();
cts.Dispose();
}
cts = new CancellationTokenSource();
var token = cts.Token;
Task.Run(async () =>
{
try
{
await Task.Delay(delay, token);
}
catch (TaskCanceledException)
{
return;
}
await Application.Current.Dispatcher.BeginInvoke(func);
});
}
这是我基于@Fabjan answer的解决方案
private static void RunSingleTask(ref CancellationTokenSource cts, int delay, Action func)
{
if (cts != null)
{
cts.Cancel();
cts.Dispose();
}
cts = new CancellationTokenSource();
var token = cts.Token;
Task.Run(async () =>
{
try
{
await Task.Delay(delay, token);
}
catch (TaskCanceledException)
{
return;
}
await Application.Current.Dispatcher.BeginInvoke(func);
});
}
制作一个bool
isRunning
。如果isRunning
为真->返回。一旦开始任务,将bool设置为true;一旦完成任务,将bool设置为false。不幸的是,我希望执行最新的任务,如果未执行上一个任务,您的建议将阻止任何输入任务。当新任务到达时,我想覆盖以前的任务使bool正在运行
。如果isRunning
为真->返回。一旦开始任务,将bool设置为true;一旦完成任务,将bool设置为false。不幸的是,我希望执行最新的任务,如果未执行上一个任务,您的建议将阻止任何输入任务。我想在新任务到达时覆盖以前的任务谢谢!这就是我需要的方向。唯一的问题是,在4.5中,您不能直接将值分配给属性,Task.Delay
在取消时会引发异常(TaskCanceledException),而且我们在这里共享一个取消令牌,因此一旦运行Cancel
方法,每次进一步的事件都会取消令牌hanks!这就是我需要的方向。唯一的问题是,在4.5中,您不能直接将值分配给属性,Task.Delay
在取消时会引发异常(TaskCanceledException),而且我们在这里共享一个取消令牌,因此一旦我们运行Cancel
方法,每次后续事件都会取消该令牌