Reputation: 533
I have an event in my WPF .NET 4.5 application that can be triggered up to 10 times per second, the event is computing data that is not required that often so I'm looking for a way to remove unnecessary computation stress and call the method if event wasn't triggered for 3 seconds. I thought about using async
functionality like that:
private async Task DoWork()
{
await Task.Delay(3000);
...
}
private void Event()
{
Task.Run(() => DoWork());
}
I'm not really sure about how to elegantly handle disposing of unwanted Tasks
, ie. when user trigger the event, every task that was created by that event should be terminated and it should be as fast as possible. I've tried with CancellationToken
but I'm not sure this is the right approach for my case
Upvotes: 0
Views: 91
Reputation: 533
That was my solution based on @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);
});
}
Upvotes: 1
Reputation: 13676
You can use CancellationTokenSource
to let the code inside task know that it is canceled:
private CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource ();
Let's change:
private async Task DoWork()
{
await Task.Delay(3000);
...
}
To:
private async Task DoWork(int timeout = 3000)
{
await Task.Delay(timeout, CancellationTokenSource.Token);
if(!CancellationTokenSource.Token.IsCancellationRequested)
{
...
}
}
Now we can cancel our task if required:
CancellationTokenSource.Cancel();
Task.Delay
will observe the CancellationToken and if it is in a Canceled state it will abort the task execution. Later in code we check whether we need to do anything or not.
Upvotes: 2