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()