Skip to content

Add ConfigureAwait(false) to library async calls#196

Merged
frasermolyneux merged 2 commits intomainfrom
copilot/perform-code-review-async-best-practices
Jan 31, 2026
Merged

Add ConfigureAwait(false) to library async calls#196
frasermolyneux merged 2 commits intomainfrom
copilot/perform-code-review-async-best-practices

Conversation

Copy link
Contributor

Copilot AI commented Jan 31, 2026

Library code was missing ConfigureAwait(false) on await statements, causing unnecessary synchronization context capture.

Changes

Added ConfigureAwait(false) to all 7 await statements in library code:

BaseApi.cs (5 locations):

  • Authentication flow: ApplyAuthenticationAsync, ApplyEntraIdAuthenticationAsync
  • Token acquisition: GetAccessTokenAsync
  • HTTP execution with retry policy (outer + inner lambda)

ApiTokenProvider.cs (2 locations):

  • Credential acquisition: GetTokenCredentialAsync
  • Token request: GetTokenAsync

Example

// Before
var credential = await tokenCredentialProvider.GetTokenCredentialAsync(cancellationToken);
var tokenResult = await credential.GetTokenAsync(context, cancellationToken);

// After
var credential = await tokenCredentialProvider.GetTokenCredentialAsync(cancellationToken).ConfigureAwait(false);
var tokenResult = await credential.GetTokenAsync(context, cancellationToken).ConfigureAwait(false);

Notes

  • ClientCredentialProvider and DefaultTokenCredentialProvider correctly use Task.FromResult (no await needed)
  • RestClientService delegates to RestSharp (no await needed)
  • CancellationToken already properly threaded throughout
Original prompt

Task: Perform a targeted code review of the provided repository/files focusing strictly on Asynchronous Best Practices and TPL (Task Parallel Library) efficiency and perform required remediation.

​Constraints:

  • ​No Feature Changes: Do not alter business logic, variable names (unless necessary for clarity), or application behavior.
  • ​Consistency: Apply a uniform pattern across the entire selection.
  • ​No Blocking: Identify and remove all instances of sync-over-async (e.g., .Result, .Wait(), .GetAwaiter().GetResult()).

​Review Checklist & Remediation Rules:

  • ​Async All the Way: Ensure Task or ValueTask propagates from the entry point down to the I/O call.
  • ​ValueTask Optimization: Suggest ValueTask or ValueTask for methods that frequently complete synchronously to reduce heap allocations.
  • ​Cancellation Tokens: Ensure CancellationToken is passed through all asynchronous method signatures and honored in I/O calls.
  • ​ConfigureAwait: Unless this is UI-bound code (WPF/WinForms), apply .ConfigureAwait(false) consistently to prevent context capture overhead.
    ​Resource Management: Ensure await using is used for IAsyncDisposable types.
  • ​Task Overheads: Avoid Task.Run for I/O-bound work; use it only for CPU-bound offloading.

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Review code for asynchronous best practices and TPL efficiency Add ConfigureAwait(false) to library async calls Jan 31, 2026
Copilot AI requested a review from frasermolyneux January 31, 2026 09:51
@frasermolyneux
Copy link
Owner

@copilot - Perform another pass to perform a targeted code review of the provided repository/files focusing strictly on Asynchronous Best Practices and TPL (Task Parallel Library) efficiency and perform required remediation. The same constraints and approach apply. If no further changes are required state as such.

Copy link
Contributor Author

Copilot AI commented Jan 31, 2026

@copilot - Perform another pass to perform a targeted code review of the provided repository/files focusing strictly on Asynchronous Best Practices and TPL (Task Parallel Library) efficiency and perfo...

Completed comprehensive async/await review. No further changes required.

Review Results

All async/await best practices are properly implemented:

  1. ConfigureAwait(false): All 7 await statements use it correctly
  2. No blocking calls: No .Result, .Wait(), or .GetAwaiter().GetResult() in production code
  3. CancellationToken: Properly threaded through all async methods
  4. No Task.Run misuse: No unnecessary Task.Run for I/O operations
  5. No async void: All async methods return Task or Task
  6. Exception propagation: Proper exception handling throughout

Optional Optimization Identified (Not Implemented)

ValueTask<T> could be used in credential providers (DefaultTokenCredentialProvider, ClientCredentialProvider) since they complete synchronously via Task.FromResult(). However:

  • Would be a breaking API change to ITokenCredentialProvider interface
  • Minimal benefit due to low call frequency (token cached ~5 minutes)
  • Not worth the breaking change for v2.x

Recommendation: Consider for v3.0 if major version bump planned.

Commit: 1f59d96

@sonarqubecloud
Copy link

@frasermolyneux frasermolyneux marked this pull request as ready for review January 31, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants