AsyncEnumerable interface can return completed Task
ndrwrbgs opened this issue · 1 comments
AsyncEnumerable/src/AsyncEnumerable.cs
Line 82 in 539aae5
Minor difference - but possibly relevant as I try to wrap the IAsyncEnumerator<T>
to the ones exposed in System.Interactive
. The line above is async
and await
s the Task
rather than just returning the Task
returned to it from the IAsyncEnumerator<T>
interface implementation. Instead, we can remove both async
and await
from this method, and allow it to return the Task.FromResult
task (which is a minor performance gain also).
There is a minor minor functional difference, in that async
wraps up in a continuation, whereas returning a Task
directly does not. This means that exceptions thrown when doing
System.Threading.Tasks.Task Demo(){
throw new Exception();
return SomeOtherTask();
}
will be thrown immediately (at a var demoTask = Demo()
rather than at the await demoTask
). However...
async System.Threading.Tasks.Task Demo2() {
throw new Exception();
await SomeOtherTask();
}
Demo2 would execute var demoTask = Demo2()
fine, but throw at await demoTask
.
All that said, this code can only throw if AsyncEnumerable.ctor
is passed a null argument, and the change in exception behavior would just make IAsyncEnumerable.GetAsyncEnumeratorAsync
match the behavior of IAsyncEnumerable<T>.GetAsyncEnumeratorAsync
, so it's probably not a breaking change, practically speaking.
@ndrwrbgs, thanks for looking into the source code.
The aforementioned line
AsyncEnumerable/src/AsyncEnumerable.cs
Line 82 in 539aae5
cannot simply cast
Task<IAsyncEnumerator<T>>
to Task<IAsyncEnumerator>
because there is no covariant ITask<out T>
interface - that's why it uses async-await
.
As for the second case, yes, I agree that Task.FromException
is the proper way to return an error. However, as you said, it might happen only in the constructor when null
is passed, so there is no real reported impact.