First of all, thank you so much for the detailed blog post explaining the basics of IValueTaskSource! I can confidently tell you there is no other place where this interface is better explained with a simple example and description of each part.
I have a few questions about your code:
- Would it help to convert the
ThrowMultipleContinuations() method into multiple static local methods (one per each method that calls it) for a perf micro improvement? This could improve the changes of having the calling method inlined (I could be wrong though, and maybe the same improvement happens if the method is not a static local method). Something like:
if (token != this.token)
{
ThrowMultipleContinuations();
}
static void ThrowMultipleContinuations() => throw new InvalidOperationException("Multiple awaiters are not allowed");
- Can you rename the private class fields so they start with an underscore character? There are some functions that reuse the same name as that from a field, and it can be confusing. For example,
GetResult creates a local variable called result, but you also have a result field in the class. While you're not explicitly using this.result, it could be misleading, hence why it's usually preferred to name class fields with underscore (look at most of the code in dotnet/runtime).
- Why did you decide to use an array in your
ObjectPool, and not a ConcurrentBag or a ConcurrentQueue instead?
- Would you consider upgrading your code to .NET 5.0 and add nullability checks? I'd also be happy to help with this last point.
First of all, thank you so much for the detailed blog post explaining the basics of
IValueTaskSource! I can confidently tell you there is no other place where this interface is better explained with a simple example and description of each part.I have a few questions about your code:
ThrowMultipleContinuations()method into multiple static local methods (one per each method that calls it) for a perf micro improvement? This could improve the changes of having the calling method inlined (I could be wrong though, and maybe the same improvement happens if the method is not a static local method). Something like:GetResultcreates a local variable calledresult, but you also have aresultfield in the class. While you're not explicitly usingthis.result, it could be misleading, hence why it's usually preferred to name class fields with underscore (look at most of the code in dotnet/runtime).ObjectPool, and not aConcurrentBagor aConcurrentQueueinstead?