我试图每隔x分钟运行一次屏幕截图任务,但似乎当我想使用给定的取消令牌取消该任务时,它似乎没有做任何事情。
这是我的开始方法代码:
var CancellationTokenSource = new CancellationTokenSource();
CancellationTokenSource?.Cancel();
CancellationTokenSource = new CancellationTokenSource();
var token = CancellationTokenSource.Token;
await RunPeriodically(async () =>
{
var screenCaptured = TakeScreenshot();
if (screenCaptured == null || CancellationTokenSource.Token.IsCancellationRequested)
return;
var correctUserName = Settings.Default.Username.Split('.');
var parsedUsername = correctUserName[0] + " " + correctUserName[1];
await ScreenshotHelper.UploadScreenshotAsync(ProjectName, "screenshotscontainer",
screenCaptured.ToArray(), Environment.MachineName, parsedUsername);
Console.WriteLine("Took Screenshot: " + DateTime.Now.ToString(CultureInfo.InvariantCulture));
}, TimeSpan.FromSeconds(3), token);
这是定期运行代码:
public async Task RunPeriodically(Action action, TimeSpan interval, CancellationToken token)
{
while (true)
{
action();
await Task.Delay(interval, token);
}
}
答案 0 :(得分:0)
我想我已经敲了一个类的快速示例,它将运行一个进程,等待一段时间并再次启动进程而不会阻塞任何线程。
class RepeatableProcess
{
private Timer processTimer;
private int delay;
private CancellationTokenSource source;
private CancellationToken token;
private Action processToRun;
private bool canStart = true;
public RepeatableProcess(int delaySeconds,Action process)
{
delay = delaySeconds;
processToRun = process;
}
public void Start()
{
if (canStart)
{
canStart = false;
source = new CancellationTokenSource();
token = source.Token;
processTimer = new Timer(TimedProcess, token, Timeout.Infinite, Timeout.Infinite);
processTimer.Change(0, Timeout.Infinite);
}
}
public void Stop()
{
source.Cancel();
}
public void TimedProcess(object state)
{
CancellationToken ct = (CancellationToken)state;
if (ct.IsCancellationRequested)
{
Console.WriteLine("Timer Stopped");
processTimer.Dispose();
canStart = true;
}
else
{
processToRun.Invoke();
processTimer.Change(delay, Timeout.Infinite);
}
}
}
Start方法创建一个永不启动且永不重复的计时器。 然后立即启动该过程,仅运行一次。
TimedProcess方法检查取消并运行指定的进程。完成此过程后,计时器将设置为在指定的延迟后启动并仅运行一次。
当计时器触发时,它从线程池中获取一个线程。不存在溢出问题,因为在进程完成之前,计时器未设置为再次运行。
这个课程需要更多保护,但这只是一个例子。 希望这会有所帮助。