Alternatives to Async Properties in C#

Current issue situation:

  • It is not allowed to have async properties in c#, it produces syntax errors, that’s why we need to look for alternatives.

  • If the property has code that could potentially be asynchronous because it has a call to, for example, a Gap.Blazor.MessageBox.Show which is an async method, the conversion tool generates an await inside the property code generating the compilation error.

Approach #1: Transform property to async methods (set and get).

This approach implies that any use of the "getter" requires an await so it can take the actual returned value instead of the task.

This approach could lead to poor legibility of the code, because of the massive amount of await sentences that could potentially be present in the code.

Example #1

Source code instance:

Migrated code instance:

The execution chain should add async and await keywords as required event for event handlers

The awaited task cannot be the entry point of the app because of some errors when it runs:

Result: It could lead to code hard to read and with slightly performance issues.

Approach #2: Changing source code, remove async modals as needed from methods that are consumed from properties

This could be the easiest solution, but could lead to problems when refactoring the customer code.

Finding

Description

Recommendation

Performance Overhead of Async Properties

Observed a slight performance overhead when using async properties due to the state machine generation.

Explore alternatives for performance-critical sections.

Complexity in Error Handling

Error handling in async properties can be complex, especially with multiple awaited operations.

Use helper methods or dedicated error handling strategies.

Testing Challenges

Unit testing async properties requires mocking and asynchronous testing patterns, adding complexity.

Develop clear testing strategies and use mocking frameworks effectively.

Alternative 1: Async Methods with Naming Convention

Using async methods (e.g., `GetAsyncValue()`) instead of async properties.

Adopt a consistent naming convention for async data retrieval.

Alternative 2: Lazy Initialization with Async Factory

Lazy initialization with an async factory method to populate the value.

Use `Lazy<Task<T>>` for delayed asynchronous initialization.

Alternative 3: Event-Based Approach

Using events to notify when the asynchronous operation completes and the value is available.

Implement event handlers and manage event subscriptions carefully.

Last updated