gpt4 book ai didi

c# - 在 Task.Factory.StartNew 中暂停任务

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

在我的 Asp.Net MVC 5 项目中,我将一个约 3 分钟的任务传递给 Task.Factory.StartNew()。

如果我在任务中运行的代码的其中一个步骤存在验证问题,我想从任务中暂停该任务。我不想将其异步延迟,因为任务的其余部分将继续运行,这是不可能发生的。

我可以在任务中使用 thread.sleep() 而不产生任何影响吗?我读到我可能必须使用 TaskScheduler.Default 来让 Task.Factory 为每个任务创建一个新线程。

我正在使用类似于 CancellationToken 的 PauseToken,因此我将能够根据用户输入恢复任务或取消此任务。

多线程真的让我害怕,我不想忽略一些东西。

这是 Thread.Sleep 实现的示例:

public void WaitIfPaused(PauseToken pauseToken, CancellationToken cancellationToken, IProgressBar progressBar)
{
//TODO: If paused for an hour notify user via noty and abort the task to keep it from completing by cancellation via cancellationToken.
//wait for 1 hour
for (int i = 0; i < 3600; i++)
{
ThrowExceptionIfCancelled(cancellationToken, progressBar);
if (pauseToken.IsPaused)
{
Thread.Sleep(1000);
}
else
{
break;
}

}
}

暂停 token :http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx


请求:在共享代码库中实现任务结构。

public void StartTask(params object[] data)
{
//throw an exception if no ITask was found
if (_taskToRun == null)
throw new Exception("Task cannot be null");

//set up task cancellation
CancellationTokenSource = new CancellationTokenSource();
var cancellationToken = CancellationTokenSource.Token;

//set up task pausing
PauseTokenSource = new PauseTokenSource();
var pauseToken = PauseTokenSource.Token;

//start a new task using the Task that was set
_task = Task.Factory.StartNew(() => _taskToRun.Execute(cancellationToken, pauseToken, data), cancellationToken);
}

我的 Execute 方法被 _taskToRun.Execute 调用:

Public override void Execute(CancellationToken cancellationToken, PauseToken pauseToken, params object[] data)
{
var managerList = (List<IFileManager>) data[0];
var instr = (List<InstructionSet>) data[1];

ProcessInstructions(managerList, instr, cancellationToken, pauseToken);
}

因评论而更新:

代码示例:3 条指令

For(var instruction in instructions)
{
instruction.Execute();
}

在我的执行方法中,我遇到了一个暂停场景,并从执行中调用 WaitWhilePausedAsync。它将继续执行其他两条指令,但只暂停当前指令的执行方法。

编辑:通过等待 instruction.Execute() 它将等到 instruction.Execute() 完成或未暂停。


最终编辑:我能够通过等待 Execute 方法并使其像 Servy 和 I3arnon 所建议的那样异步来解决问题。

最终代码示例:

foreach(var instruction in instructions)
{
try
{
await instruction.Execute(pauseToken);
}
catch(InvalidOperationException)
{
pauseTokenSource.IsPaused = true;
//ask if user wants to cancel or resume.
}
}
//Simplified
public async Task<bool> Execute(PauseToken pauseToken)
{
await pauseToken.WaitWhilePausedAsync();
//do work
}

最佳答案

您可以安全地使用Thread.Sleep。唯一的缺点是线程会被同步阻塞浪费掉。

您应该改用 await Task.Delay(1000)。该行之后的代码在等待完成之前不会执行,但同时您不会浪费线程:

public async Task WaitIfPausedAsync(PauseToken pauseToken, CancellationToken cancellationToken, IProgressBar progressBar)
{
for (int i = 0; i < 3600; i++)
{
ThrowExceptionIfCancelled(cancellationToken, progressBar);
if (pauseToken.IsPaused)
{
await Task.Delay(1000)
}
else
{
break;
}
}
}

编辑:我不知道 PauseToken.WaitWhilePausedAsync。您应该明确地使用它,而不是通过轮询 PauseToken.IsPaused

自己复制它

关于c# - 在 Task.Factory.StartNew 中暂停任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28180261/

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