You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Resource leak in IAsyncEnumerable client-side disposal: server not notified on normal enumeration completion #1386
IAsyncEnumerable<Response> GetStates(Request request, CancellationToken token = default);
and there is a property with type of IAsyncEnumerable<Operation> in request parameter.
Summary
The AsyncEnumeratorProxy in MessageFormatterEnumerableTracker.cs fails to notify the server to dispose of the enumerator when enumeration completes normally (all values consumed). This causes a resource leak on the server side where enumerators remain tracked in the generatorsByToken dictionary indefinitely.
Root Cause
In AsyncEnumeratorProxy.DisposeAsync() (line 452), the disposal notification is only sent when generatorReportsFinished is false:
if (!this.generatorReportsFinished)
{
await this.owner.jsonRpc.NotifyAsync(DisposeMethodName, this.nextOrDisposeArguments).ConfigureAwait(false);
}
However, when enumeration completes normally:
The server sets results.Finished = true (line 327)
The client receives this and sets this.generatorReportsFinished = true (line 497)
When the await foreach loop completes and DisposeAsync() is called, the condition at line 452 evaluates to false
No disposal notification is sent to the server
Impact
Memory leak: Server-side enumerators remain in generatorsByToken dictionary until connection dies
Resource leak: Any resources held by the server-side GeneratingEnumeratorTracker are not properly disposed
Accumulation: Each completed enumeration leaves behind leaked resources in long-running connections
Expected Behavior
The client should always notify the server when disposing an enumerator, regardless of whether generatorReportsFinished is true. The server needs this notification to:
Remove the enumerator from generatorsByToken dictionary
Call DisposeAsync() on the GeneratingEnumeratorTracker instance
Release any associated resources
Sorry. I see a comment at line 305-306, i.e. // Clean up all resources since we don't expect the client to send a dispose notification // since finishing the enumeration implicitly should dispose of it.
So is it by design? The client side will also clean up all resources properly, right?
Activity
javasir commentedon Jan 21, 2026
Sorry. I see a comment at line 305-306, i.e.
// Clean up all resources since we don't expect the client to send a dispose notification // since finishing the enumeration implicitly should dispose of it.So is it by design? The client side will also clean up all resources properly, right?