-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
dotnet/coreclr#14698 helped to avoid allocations when invoking methods on structs cast to interfaces, but it appears it didn't completely address it.
This code:
https://github.com/dotnet/coreclr/blob/8758f76b4e5ba6733e4f3184293414fc9182d06f/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs#L392-L398
takes advantage of this feature, and with a repro like:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
for (int i = 0; i < 100; i++)
{
await new ValueTask<int>(Task.Delay(1).ContinueWith(_ => default(int))).ConfigureAwait(false);
}
}
}
it successfully avoids the allocation, but change the int
s in the above to string
s, and it starts allocating boxes for the interface:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
for (int i = 0; i < 100; i++)
{
await new ValueTask<string>(Task.Delay(1).ContinueWith(_ => default(string))).ConfigureAwait(false);
}
}
}
@AndyAyersMS, could you take a look?
We either need to fix this for 2.1 (if you can that would be excellent), or in 2.1 I need to change the async method builder code to work a different way, as we can't have this allocation happening per await.