CancellationSource在执行Regex时不起作用



我有一个Regex,在处理某些文件时可能会导致死循环。虽然我迟早会解决这个问题,但为了安全起见,我想在可取消的任务中运行它。

我在这里读到了一些答案,但以下解决方案都不起作用。有什么帮助吗?

public static Task<CodeFile> CreateCodeFile(string fileName)
{
var fileInfo = new FileInfo(fileName);
foreach (var codeFileFactory in CodeFileFactories)
{
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(1000);
var task = new Task<CodeFile>(() => TryToCreateCodeFile(codeFileFactory, fileInfo),
cancellationTokenSource.Token);
task.RunSynchronously(); //Get lost here.
if (!task.Wait(1000))
cancellationTokenSource.Cancel();

File.WriteAllTextAsync("FailedLog.txt",
File.ReadAllTextAsync("FailedLog.txt") + "rn" + fileName);
cancellationTokenSource.Dispose();
return task;
}
return null;
}

或:

public static async Task<CodeFile> CreateCodeFile(string fileName)
{
var fileInfo = new FileInfo(fileName);
foreach (var codeFileFactory in CodeFileFactories)
{
var cancellationTokenSource = new CancellationTokenSource();

try
{
cancellationTokenSource.CancelAfter(1000);
var codeFile = await Task.Run(() => TryToCreateCodeFile(codeFileFactory, fileInfo), 
cancellationTokenSource.Token); //Get lost here.
if (codeFile != null)
return codeFile;
}
catch (TaskCanceledException)
{
File.WriteAllTextAsync("FailedLog.txt",
File.ReadAllTextAsync("FailedLog.txt") + "rn" + fileName);
}
finally
{
cancellationTokenSource.Dispose();
}
}

return null;
}

这里是要调用的函数:

private static CodeFile TryToCreateCodeFile(ICodeFileFactory codeFileFactory, FileInfo fileInfo)
{
var codeFile = codeFileFactory.CreateByName(fileInfo);
return codeFile;
//Somewhere deeper, .net Regex.Matches() caused the dead loop which I cannot control.
}

在这个主题CancellationTokenSource.Cancel不工作后,我读到了类似于";您的睡眠方法正在忽略CancellationToken"这种情况发生在我身上吗?

Cancellation令牌实现协同取消,这意味着代码是"取消";必须通过主动检查令牌的状态进行合作。Regex.Matches没有接受令牌的重载,这意味着它不能以这种方式取消。

一般来说,任务不能神奇地取消。任务执行的代码必须显式地执行(使用类似token.ThrowIfCancellationRequested()的代码(,您的代码不执行此操作,因此令牌不会执行任何有用的操作。向Task.Run传递令牌的文档如下:

一个取消令牌,如果没有,可以用来取消工作还没有开始。Run(Action,CancellationToken(未通过cancel操作的令牌。

所以,是的,若任务并没有启动,就会取消它,这在您的情况下不太有用。

如果您执行了一些不接受和处理取消令牌的长期运行操作(并且您无法通过不时检查令牌来自己处理取消(,那么您就无法使用它们来取消它。

在你的情况下,我建议Regex.MatchTimeout

最新更新