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.
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
Plugins.AspNetCore/Extensions/ApplicationBuilder.Functions.cshandler(context).ConfigureAwait(false).GetAwaiter().GetResult()Extensions.Hosting/ServiceCollection.csfactory(provider).GetAwaiter().GetResult()in DI registrationTeams.AI/Stream.csonChunk(text).GetAwaiter().GetResult()in streaming contextTeams.AI/Prompts/ChatPrompt/ChatPrompt.Errors.csonError(ex).GetAwaiter().GetResult()in event handlerImpact
SynchronizationContextSuggested 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>, anIHostedServicefor initialization, or accepting a sync factory overload.