-
I have some code that read from some source and produce an private CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
IAsyncEnumerable<Memory<byte>> GetAsyncStream([EnumeratorCancellation] CancellationToken cancellationToken = default)
{
while(true)
{
if (cancellationToken.IsCancellationRequested || CancellationTokenSource?.IsCancellationRequested == true)
{
break;
}
var result = await source.Read();
}
source.Close();
} and the caller is something like async Task MethodA()
{
var stream = GetAsyncStream();
var itor = stream.GetAsyncEnumerator();
await itor.MoveNextAsync();
var result = itor.Current;
// process result;
// and do things with A conditaion
//### should I called DisposeAsync() , and what it do in the `while(true)` loop inside `GetAsyncStream` method
}
async Task MethodB()
{
var stream = GetAsyncStream();
var itor = stream.GetAsyncEnumerator();
await itor.MoveNextAsync();
var result = itor.Current;
// process result;
// and do things with B conditaion
////### should I called DisposeAsync() , and what it do in the `while(true)` loop inside `GetAsyncStream` method
} the problemeach method get an new |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 6 replies
-
Depending on a couple of factors, you might be in trouble just if calls to
... why? Not processing the entire contents of a collection is weird. You need to process the complete collection, in one of a few ways, but you haven't provided enough details to know what your actual problem is. In particular, if you get an enumerator, not disposing of it makes your program "poorly behaved" (in the, 'not acting to spec' sense).
Some implementations may do this (eg, via a finalizer, but that's rare and possibly not a good idea), but the GC does not automatically handle this. Not knowing the lifetime of such a resource is a bug. |
Beta Was this translation helpful? Give feedback.
-
+ try {
while(true)
{
if (cancellationToken.IsCancellationRequested || CancellationTokenSource?.IsCancellationRequested == true)
{
break;
}
var result = await source.Read();
}
- source.Close();
+ } finally { source.Close(); } |
Beta Was this translation helpful? Give feedback.
-
You can check the code generation at https://sharplab.io/#v2:D4AQTAjAsAUCAMACEEAsBuWIDMyyIGFEBvWRc5XEADkQEkBBAZwE8A7AYwFE2BXAWwCmAJwCGAIwA2ggDwBLNgBcAfIgCyACgCUJMhX0oIyAOyIImGPoMQjIU2AtWKKAJzbHFAL6xPQA The cleanup of the state machine goes into |
Beta Was this translation helpful? Give feedback.
-
@huoyaoyuan @ufcpp @Clockwork-Muse @frankbolero
in fact, > it = g.GetAsyncEnumerator();
> it.MoveNextAsync()
[True]
> await it.DisposeAsync()
disposeing
> -----------------------------------
> it = g.GetAsyncEnumerator();
> await it.DisposeAsync()
> <nothing output> that means ,
and do not
|
Beta Was this translation helpful? Give feedback.
@huoyaoyuan @ufcpp @Clockwork-Muse @frankbolero
in fact,
DisposeAsync
will calling intofinally
but With One Exception :