Skip to content

ValueTask is not being properly consumed by the AwaitAdapter #4639

@RenderMichael

Description

@RenderMichael

The current implementation assumes ValueTask<> is derived from ValueTask:

public static AwaitAdapter Create(ValueTask task)
{
var genericValueTaskType = task
.GetType()
.TypeAndBaseTypes()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ValueTask<>));
if (genericValueTaskType is not null)
{
var typeArgument = genericValueTaskType.GetGenericArguments()[0];
return (AwaitAdapter)typeof(GenericAdapter<>)
.MakeGenericType(typeArgument)
.GetConstructor(new[] { typeof(ValueTask<>).MakeGenericType(typeArgument) })!
.Invoke(new object[] { task });
}
return new NonGenericAdapter(task);

This looks like a copy-paste from the Task version:

public static AwaitAdapter Create(Task task)
{
var genericTaskType = task
.GetType()
.TypeAndBaseTypes()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Task<>));
if (genericTaskType is not null)
{
var typeArgument = genericTaskType.GetGenericArguments()[0];
return (AwaitAdapter)typeof(GenericAdapter<>)
.MakeGenericType(typeArgument)
.GetConstructor(new[] { typeof(Task<>).MakeGenericType(typeArgument) })!
.Invoke(new object[] { task });
}
return new NonGenericAdapter(task);

However, ValueTask<> is a struct and cannot inherit from ValueTask, so this code was not working. Fortunately, ValueTask<>s were getting picked up by the CSharpPatternBasedAwaitAdapter, so nothing was working wrong, but this should nonetheless be fixed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions