Skip to content

Fix sync-over-async blocking calls (deadlock risk) #396

@rido-min

Description

@rido-min

Summary

Several locations in the library code use .GetAwaiter().GetResult() to synchronously block on async operations. This is a well-known anti-pattern that can cause deadlocks when the caller has a synchronization context (e.g., ASP.NET, UI frameworks) and unnecessarily blocks thread pool threads.

Locations

File Line Code
Plugins.AspNetCore/Extensions/ApplicationBuilder.Functions.cs 104 handler(context).ConfigureAwait(false).GetAwaiter().GetResult()
Extensions.Hosting/ServiceCollection.cs 102 factory(provider).GetAwaiter().GetResult() in DI registration
Teams.AI/Stream.cs 31 onChunk(text).GetAwaiter().GetResult() in streaming context
Teams.AI/Prompts/ChatPrompt/ChatPrompt.Errors.cs 16 onError(ex).GetAwaiter().GetResult() in event handler

Impact

  • Deadlock potential when called from a context with a SynchronizationContext
  • Blocks thread pool threads, reducing throughput under load
  • Defeats the purpose of async APIs

Suggested fix

Refactor the call chains to be fully async. Where a sync API surface is required (e.g., DI factory), consider using async-compatible patterns like AsyncLazy<T>, an IHostedService for initialization, or accepting a sync factory overload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions