c# - 执行正则表达式时 CancellationSource 不起作用
问题描述
在处理某些文件时,我有一个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") + "\r\n" + 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") + "\r\n" + 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.CancelAfter not working中,我读到了类似“您的睡眠方法正在忽略 CancellationToken”之类的内容。我的情况会发生这种情况吗?
解决方案
取消令牌实现合作取消,这意味着被“取消”的代码必须通过积极检查令牌的状态来进行合作。Regex.Matches
没有接受令牌的重载,这意味着它不能以这种方式取消。
一般来说,任务不能被神奇地取消。任务执行的代码必须明确地执行此操作(使用类似的东西token.ThrowIfCancellationRequested()
),您的代码不会这样做,因此令牌不会做任何有用的事情。将令牌传递给Task.Run
记录如下:
如果工作尚未开始,可用于取消工作的取消标记。Run(Action, CancellationToken) 不会将 cancelToken 传递给 action。
所以是的,如果任务没有开始,那将取消它,在你的情况下不是很有用。
如果您执行一些不接受和处理取消令牌的长时间运行的操作(并且您无法自己处理取消,通过不时检查令牌) - 那么您无法使用它们取消它。
在你的情况下,我建议Regex.MatchTimeout
推荐阅读
- angular - 在 angular firestore / firebase 中向用户展示广告字段
- ansible - Ansible - 支持或不支持 base64 编码的剧本
- python - 使用 beautifulsoup 和 Python3 抓取网页(蛋白质数据库)高度嵌套的标签
- python-3.x - 我看不懂这个石头剪刀布游戏
- c++ - 附加到 gdb 中断并且不会继续该过程
- android - 不
- ssms - MS SSMS:如何快速清除条件窗格
- css - 内容居中的 CSS 响应式正方形
- computer-vision - 如何使用椭圆检测去除睫毛噪声
- javascript - 如何将滚动速度更改为平滑?