gpt4 book ai didi

c# - 如何正确启动和取消任务。

转载 作者:太空宇宙 更新时间:2023-11-03 18:23:18 25 4
gpt4 key购买 nike

我似乎无法思考如何正确地开始和取消任务。我更改了我的代码以更容易理解我的问题并将其粘贴在下面(我还添加了一些评论)。 SubscribeToReport 方法首先被调用 - 它包含一个 await runReportTask 根据我的理解,它只会启动 runReportTask 方法,等待它完成执行,然后继续执行出现在 await 之后的代码。

runReportTask 中,我创建了一个 CancellationTokenSource 并使用 Task.Factory.StartNew() 开始了一个新任务。在任务内部,有一个 while 循环,只要任务没有被取消,它就会执行处理。根据我的理解,如果 cancellationToken.IsCancellationRequested 永远为真,我的 while 循环中的 else 将运行并且任务将停止。之后,我希望 SubscribeToReport() 继续执行 - 这不会发生,而且当我调用 cancellationTokenSource.Cancel() 时,我的代码似乎什么也没做> 在 StopReportTask() 中。我究竟做错了什么?我已经这样做了一段时间,但我似乎无法理解这应该如何工作。

private async static void SubscribeToReport()
{
Console.WriteLine("Waiting for task to finish or cancel...");

await runReportTask();

Console.WriteLine("Task has finished or was canceled."); // THIS LINE NEVER EXECUTES
}

private static CancellationTokenSource cancellationTokenSource;
private static CancellationToken cancellationToken;
private bool moreToDo = true;
private static Task runReportTask()
{
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;

return Task.Factory.StartNew(() =>
{
// Were we already canceled?
cancellationToken.ThrowIfCancellationRequested();

while(moreToDo == true)
{
if(!cancellationToken.IsCancellationRequested)
{
// Do important code here
}
else{
Console.WriteLine("Task canceled."); // THIS LINE NEVER EXECUTES WHEN CALLING StopReportTask() below
cancellationToken.ThrowIfCancellationRequested();
break;
}
}

}, cancellationToken);
}

// This method is called from another source file
private void StopReportTask()
{
Console.WriteLine("Stopping report task...");

cancellationTokenSource.Cancel();
}

最佳答案

it contains an await runReportTask which from my understanding will just start the runReportTask method, wait for it to complete execution, then resume executing the code that appear after the await.

代码:

await runReportTask();

就像这样的代码:

var task = runReportTask();
await task;

因此,明确地说,启动任务运行的是方法调用await 只是(异步地)等待它完成。

同样重要的是要注意 await 是一个异步等待。这意味着它会暂停方法的执行并返回。因此,就您的调用代码而言,SubscribeToReport 已完成执行。

(这是 problems of async void 之一;它不容易使用 - 调用代码不知道它何时完成)。

Inside runReportTask I create a CancellationTokenSource and start a new task using Task.Factory.StartNew().

作为旁注,您应该使用 Task.RunTask.Factory.StartNew is a low-level API with dangerous default settings .

it doesn't ever seem like my code does anything when I call cancellationTokenSource.Cancel() in StopReportTask()

它可能是一个不同的 cancellationTokenSource 实例。

您可以试试这个,作为测试 - 不过我不确定这是否是您想要的语义(它会导致 runReportTask 取消之前的尝试):

private static CancellationTokenSource cancellationTokenSource;
private static readonly object _mutex = new object();
private bool moreToDo = true;
private static Task runReportTask()
{
CancellationTokenSource oldCts, currentCts;
lock (_mutex)
{
oldCts = cancellationTokenSource;
currentCts = cancellationTokenSource = new CancellationTokenSource();
}
if (oldCts != null)
oldCts.Cancel();
var cancellationToken = currentCts.Token;
...
}

关于c# - 如何正确启动和取消任务。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43245350/

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