【发布时间】:2017-09-20 20:58:43
【问题描述】:
我试图每隔 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);
}
}
【问题讨论】:
-
您在
RunPeriodically方法中调用了没有await的asyncAction。而async void通常是一个糟糕的决定。重新设计。 -
我不明白为什么它没有取消,但我看到了一些其他问题:请注意,当您
await上传时,action()调用返回。所以它可能比你想象的更频繁地调用。而while(true)不会处理CancellationToken(尽管Task.Delay应该抛出TaskCancelledExceptionafaik)。 -
您实际上是在什么时候取消任务?您创建了一个新的
CancellationTokenSource,并且在此之后永远不会取消它。 -
我还建议使用 System.Threading.Timer。这将从线程池中拉出一个线程并避免阻塞线程。
标签: c# wpf xaml asynchronous async-await