gpt4 book ai didi

c# - 如何在 C# 中正确实现可取消、长时间运行的线程?

转载 作者:行者123 更新时间:2023-11-30 20:31:11 25 4
gpt4 key购买 nike

我想要一个方法来运行一些处理,最多持续一秒,休眠 5 分钟,然后重复。我还希望用户能够从 sleep 中醒来并优雅地退出。我希望它全天运行而不消耗太多系统资源。最好的设计模式是什么?

这是我的第一次尝试:

  • 我使用一个线程来等待并进行处理。我不确定是否应该使用线程、线程池线程或任务。我认为这不应该是一个任务,因为不涉及异步 IO 操作。我也不认为我应该使用计时器,因为我希望能够优雅地停止线程而不等待下一个时间间隔。
  • 我使用 AutoResetEvents 在两个线程之间发出信号。这允许内部代码在时间到了或用户想要退出时运行。
  • 如果这个问题重复,我深表歉意。如果是这样,我找不到它。

这是我的代码:

var areCanContinue = new AutoResetEvent(false);
bool shouldContinue = true;

var thread = new Thread(obj =>
{
while (true)
{
areCanContinue.WaitOne(TimeSpan.FromMinutes(5));
if (shouldContinue)
{
Process();
}
else
{
break;
}
}
});
thread.Start();

string response;
do
{
Console.WriteLine("Press 'q' to quit");
response = Console.ReadLine();
} while (response != "q");

shouldContinue = false;
areCanContinue.Set();

最佳答案

任务不一定适用于 I/O 绑定(bind)操作。事实上,这是 Task.Delay(内部包装了一个计时器)的一个很好的用例:

public static async Task ProcessAsync(CancellationToken cancellationToken)
{
try
{
while (true)
{
await Task.Delay(TimeSpan.FromMinutes(5), cancellationToken).ConfigureAwait(false);

Process();
}
}
catch (TaskCanceledException)
{
// Cancellation requested, do whatever cleanup you need then exit gracefully
}
}

然后使用它:

var cancellationTokenSource = new CancellationTokenSource();

var task = ProcessAsync(cancellationTokenSource.Token);

string response;
do
{
Console.WriteLine("Press 'q' to quit");
response = Console.ReadLine();
} while (response != "q");

cancellationTokenSource.Cancel();

task.Wait(); // Wait for the task to finish

根据您的要求,您也可以直接使用计时器:

var timer = new Timer(_ => Process(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));

string response;
do
{
Console.WriteLine("Press 'q' to quit");
response = Console.ReadLine();
} while (response != "q");

timer.Dispose(); // Stop the timer

关于c# - 如何在 C# 中正确实现可取消、长时间运行的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43597450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com