是否有可能中止长时间执行的同步方法?
我有调用LongRunningMethod
方法的方法Test,该方法消耗大量内存和CPU,如果它持续时间超过30秒,我想中止它。然而,在抛出异常之后,CPU和内存仍然在增加,尽管任务已经完成。
代码:
static async Task<string> Test (string input)
{
var tokenSource = new CancellationTokenSource();
var task = LongRunningMethod(input, tokenSource.Token)
.WaitAsync(TimeSpan.FromSeconds(30));
try
{
var result = await task;
return result;
}
catch (Exception ex)
{
// if the timeout is thrown, the LongRunningMethod still executes in background
// and increase memory and CPU
}
}
static Task<string> LongRunningMethod(string input, CancellationToken token)
{
var task= Task.Run(() =>
{
SynchronousMethodThatConsumesMemoryAndCpu(input);
return "end";
},
token);
return task;
}
我不想优化它或写它不同,我问是否有可能中止该方法的执行,如果我不能传递CancellationToken。
不,没有。没有官方的辅助方法或其他机制来取消/中止不提供取消/中止机制(例如接受令牌)的方法。
此外,在2022年3月关于非合作终止代码执行的提案#66480的评论中,微软的。net性能专家Stephen Toub写了很多关于任务和线程的文章,他说:
我们已经在。net Core中删除了一大堆代码,这些代码本来是用来帮助提高面对线程终止时的可靠性的(…)
新代码也假定没有线程中止。(…)
这意味着使用Thread.Interrupt
的把戏现在更加危险了。
看起来你必须:
- 在单独的进程中运行该方法;或
- 让方法运行到完成,如果30秒过去了就忽略它的结果。