Description
The SystemTransactionContext
uses following field: private readonly AsyncLocal<bool> _bypassLock = new AsyncLocal<bool>();
By design, each creation of the 'SystemTransactionContext' (specifically the '_bypassLock' field) adds a new item into ExecutionContext._localValues
dictionary and each assignment to _bypassLock.Value
creates a copy of ExecutionContext._localValues
dictionary.
So if you run many transactions in one execution context (it can be a background job thread or main thread in a console application) the ExecutionContext._localValues
dictionary gets bigger and bigger which causes
- Memory leak issues
- Performance issues (as assigning to the '_bypassLock.Value' creates a copy of dictionary with a lot of items).
I have checked the code and at first glance it seems to me that the _bypassLock field could be made static as each thread gets its own copy of the execution context. I have created a unit test and a proposed fix (see pull request 1596).
However I understand that the unit test is not 100% correct as it's using reflection to get the .NET system private dictionary (ExecutionContext._localValues
) which might change in future versions of .NET, but I don't have an idea how to write the test more correctly.
Please check the proposed solution and / or comment the issue.