I am kicking off a few tasks to match regular expressions within a long string.
My list of tasks looks like this:
var splittingTasks = new List<Task>();
foreach (var keyword in _general.Keywords)
{
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
await Task.WhenAll(splittingTasks);
and the SplitMatches method looks like this:
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);
});
}
Debugging the await Task.WhenAll(splittingTasks); results to a NullReferenceException for keyword: 'keyword' threw an exception of type 'System.NullReferenceException'. Nevertheless the result is as expected.
I read this post where it says that the lambda expression within a for loop can cause problems since the delegate is not evaluated immediately.
But even after copying the variable inside the foreach loop I am still getting the same error.
foreach (var kw in _general.Keywords)
{
string keyword = kw;
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
Do you have any advice?
EDIT:
My keywords list _general.Keywords is imported from an appsettings.json file via the options pattern. However, trying the following approach produces the same debugging error:
List<string> keywords = new()
{
"keyword1",
"keyword2",
"keyword3",
"keyword4",
"keyword5"
};
foreach (var kw in keywords)
{
string keyword = kw;
splittingTasks.Add(Task.Run(() => SplitMatches(keyword)));
}
EDIT2:
Correct me if I am wrong but I think the error comes from debugging only. Since the Tasks exist outside of the loop but keyword does not. So the debugger tries to access the last value of keyword which is not declared in the scope. Declaring the variable keyword outside of the foreach produces no errors, BUT in turn the result is just plain wrong. Can I just ignore this error?
EDIT3:
foreach (var task in splittingTasks)
{
Console.WriteLine(task.IsCompletedSuccessfully.ToString());
}
Returns true for all tasks. And there are not more tasks than expected! (For mentioned list in the first EDIT it would be 5 tasks)
EDIT4:
I uploaded a short video displaying the problem of Visual Studio
Seems to me like VS is evaluating the variable keyword even before it is declared in the for loop. I cannot understand why and I couldn't find a way to even throw this error.
EDIT5:
you can find a minimal reproducible example here
Copy paste in visual studio and try to debug the method GetKeywordMatchesAsync()
