c# - 启动 ForEach 内的任务调试 NullReferenceException
问题描述
我正在启动一些任务来匹配长字符串中的正则表达式。
我的任务列表如下所示:
var splittingTasks = new List<Task>();
foreach (var keyword in _general.Keywords)
{
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
await Task.WhenAll(splittingTasks);
该SplitMatches
方法如下所示:
ConcurrentBag<string> _objectifiableMatches = new();
//...
public void SplitMatches(string keyword)
{
string patternObject = $@"\/begin {keyword}[\s\S]+?\/end {keyword}";
Regex regexObject = new(patternObject);
MatchCollection Matches = regexObject.Matches(_content);
Parallel.ForEach(Matches, m =>
{
var replacedQuotes = m.Value.Replace($"\"", "'");
_objectifiableMatches.Add(replacedQuotes);
});
}
await Task.WhenAll(splittingTasks);
将结果调试到NullReferenceException
for keyword
: 'keyword' threw an exception of type 'System.NullReferenceException'
。尽管如此,结果还是如预期的那样。
我读了这篇文章,其中说 for 循环中的 lambda 表达式可能会导致问题,因为不会立即评估委托。但即使在foreach
循环内复制变量后,我仍然遇到同样的错误。
foreach (var kw in _general.Keywords)
{
string keyword = kw;
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
你有什么建议吗?
编辑:
我的关键字列表是通过选项模式_general.Keywords
从文件中导入的。appsettings.json
但是,尝试以下方法会产生相同的调试错误:
List<string> keywords = new()
{
"keyword1",
"keyword2",
"keyword3",
"keyword4",
"keyword5"
};
foreach (var kw in keywords)
{
string keyword = kw;
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
EDIT2:如果我错了,请纠正我,但我认为错误仅来自调试。由于任务存在于循环之外但keyword
不存在。因此调试器尝试访问未在作用域中声明的关键字的最后一个值。keyword
在外部声明变量foreach
不会产生错误,但结果却是完全错误的。我可以忽略这个错误吗?
编辑3:
foreach (var task in splittingTasks)
{
Console.WriteLine(task.IsCompletedSuccessfully.ToString());
}
返回true
所有任务。而且没有比预期更多的任务!(对于第一个编辑中提到的列表,它将是 5 个任务)
EDIT4:
我上传了一个简短的视频,展示了 Visual Studio 的问题,
在我看来,VSkeyword
甚至在它在 for 循环中声明之前就正在评估该变量。我不明白为什么,我什至找不到抛出这个错误的方法。
EDIT5:您可以在此处
找到一个最小的可重现示例
在 Visual Studio 中复制粘贴并尝试调试该方法GetKeywordMatchesAsync()
解决方案
推荐阅读
- ruby-on-rails - 将 rails 应用程序部署到 Heroku 错误 ArgumentError:无效选项:和谐
- node.js - 如何从 node.js 中的连续图像流创建 MediaStream 轨道?(用于 WebRTC)
- python - __init__() 接受 1 个位置参数,但给出了 3 个
- karate - 如何在空手道中测试数组的顺序
- ios - 我试图重新创建从一个屏幕到另一个屏幕的表格视图,但不断收到错误信号 sigbart
- json - 从成功的 Invoke-RestMethod 中选择对象数据失败
- node.js - 模式尚未注册模型错误显示
- javascript - 有没有一种方法可以动态增加使用 ajax、php 和纯 js 显示在 html 页面上的项目数
- excel - Excel 键盘能够更改显示的动态图表范围行中的值
- mongo-go - 使用 mongodb-go-driver 如何获取内部异常