Как запустить задачу, используя только последний триггер в течение х секунд?
У меня есть функция, которая запускает задачу для запуска.
void function ()
{
new Task(async () =>
{
// await network operation
}).Start();
}
Функция может вызываться много раз очень часто. Но я не хочу, чтобы Задача запускалась каждый раз, я хочу, чтобы она запускалась только на последнем триггере в течение, скажем, 5 секунд.
Вот шаги к тому, что я хочу сделать именно
- функция () вызывается
- Задержка на 5 секунд
- если функция () была вызвана в течение этих 5 секунд, я хочу отменить все отложенные задачи и снова начать задержку в 5 секунд
- Если функция () не была вызвана в течение этих 5 секунд, я хочу запустить задачу
Пожалуйста, наставьте меня, как я это сделаю в C# .NET 4.5
1 ответ
В следующем коде показано простое консольное приложение, которое запускает задачу через 5 секунд и отменяет текущую задачу, если запускается новая:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting");
Console.WriteLine("Press any key to call method or press Esc to cancel");
do
{
Method();
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
static Task delayTask = null;
static CancellationTokenSource cancellationTokenSource = null;
static void Method()
{
Console.WriteLine("Method called");
if (delayTask != null)
{
cancellationTokenSource.Cancel();
}
cancellationTokenSource = new CancellationTokenSource();
delayTask = Task.Delay(5000, cancellationTokenSource.Token);
delayTask.ContinueWith((t) => {
Console.WriteLine("Task running...");
}, TaskContinuationOptions.NotOnCanceled);
}
}
Код не использует async/await, потому что их нельзя легко использовать в консольном приложении (консольное приложение не имеет SynchronizationContext
). При использовании этого кода в приложении WinForms, WPF или ASP.NET вы можете легко использовать async/await для улучшения кода. Тем не менее, он показывает основную идею использования CancellationTokenSource
и объединение задержки с другой задачей.
Обычным термином для этого будет "debounce", и он обсуждается здесь: C# event debounce