-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed as not planned
Closed as not planned
Copy link
Labels
Description
Sample code
while (true)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
scope.Complete();
}
}Memory usage grows, and response times increase until the web api halts. Removing the async option resolves the issue, but async is required in my case. 😞
Workaround (not perfect, see comment)
I created a factory (singleton) around it to manually trigger GC, something like this simplified:
public class TransactionScopeFactory
{
private const int GcThreshold = 200_000;
private static int _createdScopes = 0;
public TransactionScope CreateScope()
{
int currentCreatedScopes = Interlocked.Increment(ref _createdScopes);
if (currentCreatedScopes >= GcThreshold)
{
if (Interlocked.CompareExchange(ref _createdScopes, 0, GcThreshold) >= GcThreshold)
{
GC.Collect(2);
}
}
return new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
}
}Questions
- Is the workaround okay? I'm a bit hesitant about manual GC, as the docs advises against it without a clear purpose and the TransactionScope docs doesn't mention anything about manually invoking GC.
- Why does the workaround only work in release mode? It doesn't seem to work in debug mode.
Used versions: .NET 8, 9
Thank you 😄
julealgon and antoniofreire
