Skip to content

VSTHRD200 calculates all awaitable types, but only caches one #829

Open

Description

@sharwell

This block calculates all awaitable types, but only caches the one requested by an argument. This results in a large amount of recalculation.

IEnumerable<ITypeSymbol>? awaitableTypesFromThisAssembly = from candidateAwaiterMethod in compilation.GetSymbolsWithName(m => m == GetAwaiterMethodName, SymbolFilter.Member, cancellationToken).OfType<IMethodSymbol>()
where candidateAwaiterMethod.IsExtensionMethod && !candidateAwaiterMethod.Parameters.IsEmpty
where ConformsToAwaiterPattern(candidateAwaiterMethod.ReturnType)
select candidateAwaiterMethod.Parameters[0].Type;
IEnumerable<ITypeSymbol>? awaitableTypesPerAssembly = from assembly in compilation.Assembly.Modules.First().ReferencedAssemblySymbols
from awaitableType in GetAwaitableTypes(assembly)
select awaitableType;
isAwaitable = awaitableTypesFromThisAssembly.Concat(awaitableTypesPerAssembly).Contains(typeSymbol);

Activity

  1. AArnott commented on Apr 20, 2021

    @AArnott
    Member

    Nice catch. That doesn't appear to find all awaitable types (it filters by candidateAwaiterMethod.IsExtensionMethod and not all awaitable types are by extensions method), but we should certainly cache all the data that we have computed.

  2. sharwell commented on Apr 20, 2021

    @sharwell
    ContributorAuthor

    It does filter by IsExtensionMethod, but perhaps it could specifically all known awaitable types created by extension methods? This would make it a true one-time calculation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions