### Configuration Guide Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt End-to-end guide for configuring the library across development, staging, and production environments, complete with real integration examples. ```APIDOC ## Configuration Guide ### Description This guide covers end-to-end configuration patterns for the library, applicable to development, staging, and production environments. It includes practical examples demonstrating real integration scenarios. ### Configuration Patterns - **Environment-Specific Settings**: Guidance on how to configure the library differently for development, staging, and production. - **Integration Examples**: Real-world examples showing how to integrate the configuration into your application. - **Best Practices**: Recommendations for secure and efficient configuration management. ``` -------------------------------- ### Global exception handling setup Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Provides an example of setting up global exception handling for asynchronous operations. ```csharp TaskScheduler.UnobservedTaskException += (sender, args) => { Console.WriteLine($"Global unobserved task exception: {args.Exception.InnerException.Message}"); args.SetObserved(); }; ``` -------------------------------- ### Practical Examples Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt Illustrates real-world usage patterns for key features such as fire-and-forget, weak events, MVVM commands, and configuration. These examples demonstrate how to effectively integrate and utilize the library's capabilities. ```APIDOC ## Practical Examples ### Description Demonstrates practical, real-world usage patterns for various features of the library. These examples are designed to help developers understand how to apply the library's concepts in common scenarios. ### Usage Patterns Covered - **Fire-and-Forget**: Examples showing how to initiate asynchronous operations without awaiting their completion. - **Weak Events**: Demonstrations of implementing and using weak event patterns to prevent memory leaks. - **MVVM Commands**: Code examples illustrating the integration of asynchronous operations with MVVM command patterns. - **Configuration**: Practical examples for setting up and managing library configuration across different environments. - **Error Handling**: Scenarios showcasing effective error handling strategies within asynchronous code. ### Examples - 50+ real-world code examples are provided, covering the above patterns and more. ``` -------------------------------- ### Complete Usage Example with EventHandler Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/WeakEventManager.md Demonstrates the complete setup for using WeakEventManager with a standard EventHandler, including adding subscribers and raising events. ```csharp public class CommandBase { readonly WeakEventManager _canExecuteChangedManager = new(); public event EventHandler CanExecuteChanged { add => _canExecuteChangedManager.AddEventHandler(value); remove => _canExecuteChangedManager.RemoveEventHandler(value); } public void RaiseCanExecuteChanged() { _canExecuteChangedManager.RaiseEvent( this, EventArgs.Empty, nameof(CanExecuteChanged) ); } } ``` -------------------------------- ### Configuration Scenario: Development Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Example of setting up development-specific configurations, potentially enabling more verbose logging or debugging features. ```csharp AsyncManager.Initialize(); AsyncManager.SetDefaultExceptionHandling(ex => { Console.WriteLine($"Dev Exception: {ex.Message}"); }); // Other development-specific settings... ``` -------------------------------- ### Configuration for different environments Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Provides examples of configuring the library for different environments, such as development and production. ```csharp // Development configuration Configuration.SetEnvironment(Environment.Development); Configuration.EnableDetailedLogging(); // Production configuration Configuration.SetEnvironment(Environment.Production); Configuration.DisableLogging(); ``` -------------------------------- ### AsyncCommand Usage Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Illustrates creating and using an AsyncCommand with distinct types for execution and can-execute parameters. The example shows checking executability before executing the command. ```csharp var command = new AsyncCommand( execute: async (input) => { await ProcessAsync(input); }, canExecute: (value) => !string.IsNullOrEmpty(value) ); if (command.CanExecute("data")) await command.ExecuteAsync("data"); ``` -------------------------------- ### AsyncCommand ExecuteAsync Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Demonstrates creating and executing an AsyncCommand with a typed parameter. The example shows both asynchronous execution using ExecuteAsync and synchronous fire-and-forget execution using the ICommand.Execute method. ```csharp var command = new AsyncCommand( execute: async (delay) => { await Task.Delay(delay); Console.WriteLine("Delayed completion"); } ); await command.ExecuteAsync(5000); command.Execute(5000); // Fire and forget ``` -------------------------------- ### Configuration Scenario: Production Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Example of configuring the system for production, typically focusing on performance and robust error handling with minimal overhead. ```csharp AsyncManager.Initialize(); AsyncManager.SetDefaultExceptionHandling(ex => { // Log to a production-ready logging service ProductionLogger.Log(ex); }); // Production-specific configurations... ``` -------------------------------- ### Example Usage of AsyncValueCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices.MVVM/README.md Demonstrates the instantiation and usage of various AsyncValueCommand configurations within a class, including commands with parameters, can-execute logic, and exception handling. ```csharp public class ExampleClass { bool _isBusy; public ExampleClass() { ExampleValueTaskCommand = new AsyncValueCommand(ExampleValueTaskMethod); ExampleValueTaskIntCommand = new AsyncValueCommand(ExampleValueTaskMethodWithIntParameter); ExampleValueTaskIntCommandWithCanExecute = new AsyncValueCommand(ExampleValueTaskMethodWithIntParameter, CanExecuteInt); ExampleValueTaskExceptionCommand = new AsyncValueCommand(ExampleValueTaskMethodWithException, onException: ex => Debug.WriteLine(ex.ToString())); ExampleValueTaskCommandWithCanExecuteChanged = new AsyncValueCommand(ExampleValueTaskMethod, _ => !IsBusy); ExampleValueTaskCommandReturningToTheCallingThread = new AsyncValueCommand(ExampleValueTaskMethod, continueOnCapturedContext: true); } public IAsyncValueCommand ExampleValueTaskCommand { get; } public IAsyncValueCommand ExampleValueTaskIntCommand { get; } public IAsyncCommand ExampleValueTaskIntCommandWithCanExecute { get; } public IAsyncValueCommand ExampleValueTaskExceptionCommand { get; } public IAsyncValueCommand ExampleValueTaskCommandWithCanExecuteChanged { get; } public IAsyncValueCommand ExampleValueTaskCommandReturningToTheCallingThread { get; } public bool IsBusy { get => _isBusy; set { if (_isBusy != value) { _isBusy = value; ExampleValueTaskCommandWithCanExecuteChanged.RaiseCanExecuteChanged(); } } } async ValueTask ExampleValueTaskMethod() { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(1000); } async ValueTask ExampleValueTaskMethodWithIntParameter(int parameter) { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(parameter); } async ValueTask ExampleValueTaskMethodWithException() { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(1000); throw new Exception(); } bool CanExecuteInt(int count) { if(count > 2) return true; return false; } void ExecuteCommands() { _isBusy = true; try { ExampleValueTaskCommand.Execute(null); ExampleValueTaskIntCommand.Execute(1000); ExampleValueTaskExceptionCommand.Execute(null); ExampleValueTaskCommandReturningToTheCallingThread.Execute(null); if (ExampleValueTaskCommandWithCanExecuteChanged.CanExecute(null)) ExampleValueTaskCommandWithCanExecuteChanged.Execute(null); if(ExampleValueTaskIntCommandWithCanExecute.CanExecute(2)) ExampleValueTaskIntCommandWithCanExecute.Execute(2); } finally { _isBusy = false; } } } ``` -------------------------------- ### AsyncCommand ExecuteAsync Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Demonstrates how to create and use an AsyncCommand with no parameters. The ExecuteAsync method can be awaited for completion, while the ICommand.Execute method fires and forgets. ```csharp var command = new AsyncCommand( execute: async () => { await Task.Delay(1000); Console.WriteLine("Done"); } ); // Using ExecuteAsync await command.ExecuteAsync(); // Using ICommand.Execute (fires and forgets) command.Execute(null); ``` -------------------------------- ### Contravariance Example with IAsyncCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/types.md Demonstrates how contravariance allows assigning a command with a more specific type to a variable of a less specific type. ```csharp IAsyncCommand cmdObject = new AsyncCommand(async x => {}); // Allowed: string is contravariant to object ``` -------------------------------- ### AsyncCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt Documentation for the AsyncCommand module, detailing 3 interface types, 3 class variants with constructors, and 5 usage patterns with examples for implementing asynchronous commands. ```APIDOC ## AsyncCommand ### Description Provides implementations for asynchronous commands, suitable for use in MVVM patterns where asynchronous operations need to be executed by UI actions. ### Interfaces - `IAsyncCommand` - `IAsyncCommand` - `IAsyncCommand` ### Classes - `AsyncCommand` - `AsyncCommand` - `AsyncCommand` Each class includes constructors for initialization. ### Usage Patterns Includes 5 distinct usage patterns with code examples demonstrating how to integrate `AsyncCommand` into various scenarios, including handling execution and can-execute logic asynchronously. ``` -------------------------------- ### SafeFireAndForget ValueTask Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Safely execute a ValueTask without waiting for its completion. Exceptions can be handled via an optional callback, otherwise they will be rethrown. ```csharp async ValueTask ProcessAsync() { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(100); } ProcessAsync().SafeFireAndForget( onException: ex => Debug.WriteLine(ex) ); ``` -------------------------------- ### SafeFireAndForget Task Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Safely execute a Task without awaiting its completion. An optional callback can handle exceptions. If no callback is provided, exceptions will be rethrown. ```csharp async Task FetchDataAsync() { await Task.Delay(1000); // Do work } void HandleButton() { FetchDataAsync().SafeFireAndForget( onException: ex => Console.WriteLine($"Error: {ex.Message}") ); // Method returns immediately without awaiting FetchDataAsync } ``` -------------------------------- ### ViewModel with AsyncCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/README.md Define an asynchronous command within a ViewModel using the AsyncCommand class. This example shows initialization with execute, canExecute, and exception handling delegates. ```csharp public class ViewModel { public IAsyncCommand SaveCommand { get; } public ViewModel() { SaveCommand = new AsyncCommand( execute: SaveAsync, canExecute: () => !IsSaving, onException: HandleSaveError ); } private async Task SaveAsync() { } private void HandleSaveError(Exception ex) { } } ``` -------------------------------- ### Parameter type error scenarios Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Shows examples of runtime errors that can occur due to incorrect parameter types passed to commands. ```csharp // Assuming ProcessItemCommand expects a string // This would throw an InvalidCommandParameterException if executed with an int // await ProcessItemCommand.ExecuteAsync(123); ``` -------------------------------- ### Using WeakEventManager with Action Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/WeakEventManager.md This example demonstrates using WeakEventManager with a custom delegate type, Action. It illustrates the flexibility of the manager in supporting different delegate signatures for events. ```csharp public class ViewModel { readonly WeakEventManager _countChangedManager = new(); public event Action CountChanged { add => _countChangedManager.AddEventHandler(value); remove => _countChangedManager.RemoveEventHandler(value); } void OnCountChanged(int newCount) { _countChangedManager.RaiseEvent(newCount, nameof(CountChanged)); } } ``` -------------------------------- ### Complete API Reference Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt Details every exported class, interface, method, and property with full signatures, parameter tables, return types, and examples. This section serves as the primary reference for understanding the library's public surface. ```APIDOC ## API Reference ### Description Provides a complete reference for all exported components of the library, including classes, interfaces, methods, and properties. Each documented item includes its full signature, parameter details, return types, and usage examples. ### Details - **Classes**: All exported classes are documented. - **Interfaces**: All exported interfaces are documented. - **Methods**: All exported methods are documented with signatures and parameter tables. - **Properties**: All exported properties are documented. - **Signatures**: Full method and function signatures are provided. - **Parameters**: Documented with type, name, and description in tables. - **Return Types**: Clearly specified for all methods and functions. - **Examples**: Code examples are provided for each documented API element. ``` -------------------------------- ### SafeFireAndForget Task with Generic Exception Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Safely execute a Task without awaiting, specifically catching and handling exceptions of a specified type TException. This allows for targeted error handling. ```csharp ExampleAsyncMethod().SafeFireAndForget( onException: ex => Console.WriteLine($"Web Error: {ex.Status}") ); ``` -------------------------------- ### ExampleClass Demonstrating AsyncCommand Usage Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices.MVVM/README.md Demonstrates the instantiation and usage of various AsyncCommand types within a ViewModel, including commands with parameters, can-execute logic, and exception handling. ```csharp public class ExampleClass { bool _isBusy; public ExampleClass() { ExampleAsyncCommand = new AsyncCommand(ExampleAsyncMethod); ExampleAsyncIntCommand = new AsyncCommand(ExampleAsyncMethodWithIntParameter); ExampleAsyncIntCommandWithCanExecute = new AsyncCommand(ExampleAsyncMethodWithIntParameter, CanExecuteInt); ExampleAsyncExceptionCommand = new AsyncCommand(ExampleAsyncMethodWithException, onException: ex => Console.WriteLine(ex.ToString())); ExampleAsyncCommandWithCanExecuteChanged = new AsyncCommand(ExampleAsyncMethod, _ => !IsBusy); ExampleAsyncCommandReturningToTheCallingThread = new AsyncCommand(ExampleAsyncMethod, continueOnCapturedContext: true); } public IAsyncCommand ExampleAsyncCommand { get; } public IAsyncCommand ExampleAsyncIntCommand { get; } public IAsyncCommand ExampleAsyncIntCommandWithCanExecute { get; } public IAsyncCommand ExampleAsyncExceptionCommand { get; } public IAsyncCommand ExampleAsyncCommandWithCanExecuteChanged { get; } public IAsyncCommand ExampleAsyncCommandReturningToTheCallingThread { get; } public bool IsBusy { get => _isBusy; set { if (_isBusy != value) { _isBusy = value; ExampleAsyncCommandWithCanExecuteChanged.RaiseCanExecuteChanged(); } } } async Task ExampleAsyncMethod() { await Task.Delay(1000); } async Task ExampleAsyncMethodWithIntParameter(int parameter) { await Task.Delay(parameter); } async Task ExampleAsyncMethodWithException() { await Task.Delay(1000); throw new Exception(); } bool CanExecuteInt(int count) { if(count > 2) return true; return false; } void ExecuteCommands() { _isBusy = true; try { ExampleAsyncCommand.Execute(null); ExampleAsyncIntCommand.Execute(1000); ExampleAsyncExceptionCommand.Execute(null); ExampleAsyncCommandReturningToTheCallingThread.Execute(null); if(ExampleAsyncCommandWithCanExecuteChanged.CanExecute(null)) ExampleAsyncCommandWithCanExecuteChanged.Execute(null); if(ExampleAsyncIntCommandWithCanExecute.CanExecute(1)) ExampleAsyncIntCommandWithCanExecute.Execute(1); } finally { _isBusy = false; } } } ``` -------------------------------- ### Integration patterns (logging, crash reporting, analytics) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Demonstrates how to integrate the library with external systems for logging, crash reporting, and analytics. ```csharp // Setup logging integration Configuration.SetExceptionHandler(exception => Logger.Log(exception)); // Setup analytics integration Configuration.SetCompletionHandler(result => Analytics.Track("OperationCompleted", result)); ``` -------------------------------- ### Initialize Default Exception Handling Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Sets up global default exception handling for the library. This method should be called once during application startup. ```csharp AsyncManager.Initialize(); ``` -------------------------------- ### Delayed Failure Example Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Illustrates that invalid configurations for SafeFireAndForgetExtensions, such as rethrowing exceptions in handlers, do not fail immediately but only when a task subsequently throws an exception. ```csharp // This doesn't fail immediately SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { throw ex; // Rethrowing in handler - will fail when exception occurs }); // This doesn't fail immediately SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: true); // These fail when a task throws: SomeTask().SafeFireAndForget(); ``` -------------------------------- ### Initialize Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Initializes global SafeFireAndForget behavior, with an option to always rethrow exceptions for debugging purposes. ```APIDOC ## Initialize ### Description Initializes global SafeFireAndForget behavior. This method allows setting a global flag to control whether exceptions should always be rethrown after handling, which is primarily useful for debugging. ### Method Signature ```csharp public static void Initialize(bool shouldAlwaysRethrowException = false) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **shouldAlwaysRethrowException** (bool) - Optional - If true, all exceptions are always rethrown after handling. Defaults to false. Use with caution, as this can crash the application. ### Remarks When `shouldAlwaysRethrowException` is true, exceptions will always be rethrown after `onException` handlers execute. This is dangerous and should only be used during development/debugging. There is no way to catch rethrown exceptions; they will crash the application. ### Example ```csharp SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: false); ``` ``` -------------------------------- ### Basic Usage of SafeFireAndForget with Task Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices/README.md Demonstrates how to use SafeFireAndForget to execute an async Task method without awaiting its completion. Includes an exception handler to log errors to the console. ```csharp void HandleButtonTapped(object sender, EventArgs e) { // Allows the async Task method to safely run on a different thread while the calling thread continues, not awaiting its completion // onException: If an Exception is thrown, print it to the Console ExampleAsyncMethod().SafeFireAndForget(onException: ex => Console.WriteLine(ex)); // HandleButtonTapped continues execution here while `ExampleAsyncMethod()` is running on a different thread // ... } async Task ExampleAsyncMethod() { await Task.Delay(1000); } ``` -------------------------------- ### Handling InvalidCommandParameterException in AsyncCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/errors.md Provides an example of catching InvalidCommandParameterException when executing an AsyncCommand. This is useful for logging warnings and validating input types before they are passed to the command. ```csharp try { command.Execute(userInput); } catch (InvalidCommandParameterException ex) { // Wrong parameter type provided Logger.Warn($"Invalid command parameter: {ex.Message}"); // Validate input type before passing to command } ``` -------------------------------- ### ExecuteAsync and CanExecute with distinct parameter types Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Demonstrates executing a command with a specific parameter type (TExecute) after checking its executability with a potentially different parameter type (TCanExecute). This pattern is useful for commands where the condition to execute differs from the data required for execution. ```csharp public ValueTask ExecuteAsync(TExecute parameter) ``` ```csharp public bool CanExecute(TCanExecute parameter) ``` ```csharp var command = new AsyncValueCommand( execute: async (input) => { var random = new Random(); if (random.Next(10) > 9) await ProcessAsync(input); }, canExecute: (value) => !string.IsNullOrEmpty(value) ); if (command.CanExecute("data")) await command.ExecuteAsync("data"); ``` -------------------------------- ### Safe Fire-and-Forget with ConfigureAwaitOptions (.NET 8+) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/README.md For .NET 8 and later, this extension method allows specifying ConfigureAwaitOptions along with safe fire-and-forget execution for Tasks. This provides finer control over synchronization context capture. ```csharp await Task.Run(async () => { await Task.Delay(1000); throw new InvalidOperationException("Something went wrong!"); }).ConfigureAwait(ConfigureAwaitOptions.None).SafeFireAndForget(ex => { /* Handle exception here */ }); ``` -------------------------------- ### Initialize and Configure SafeFireAndForget Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices/README.md Initializes the SafeFireAndForget extension with a specified exception rethrow behavior and sets up default exception handling. Use `shouldAlwaysRethrowException: false` in production. ```csharp void InitializeSafeFireAndForget() { // Initialize SafeFireAndForget // Only use `shouldAlwaysRethrowException: true` when you want `.SafeFireAndForget()` to always rethrow every exception. This is not recommended, because there is no way to catch an Exception rethrown by `SafeFireAndForget()`; `shouldAlwaysRethrowException: true` should **not** be used in Production/Release builds. SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: false); // SafeFireAndForget will print every exception to the Console SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => Console.WriteLine(ex)); } void UninitializeSafeFireAndForget() { // Remove default exception handling SafeFireAndForgetExtensions.RemoveDefaultExceptionHandling() } ``` -------------------------------- ### AsyncCommand Constructor (No Parameters) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Initializes a new instance of the AsyncCommand class with no execute or canExecute parameters. It accepts an asynchronous execute function, an optional synchronous canExecute function, an optional exception handler, and a boolean to control context continuation. ```csharp public class AsyncCommand : BaseAsyncCommand, IAsyncCommand { public AsyncCommand( Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) } ``` -------------------------------- ### Configuration Scenario: Crash Reporting Integration Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Demonstrates integrating a third-party crash reporting service with the default exception handling mechanism. ```csharp AsyncManager.Initialize(); AsyncManager.SetDefaultExceptionHandling(ex => { CrashReporter.Report(ex); }); ``` -------------------------------- ### SafeFireAndForget for Task with ConfigureAwaitOptions (.NET 8+) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Safely executes a Task on .NET 8.0+ using ConfigureAwaitOptions for fine-grained control over await behavior. Use this for advanced scenarios requiring specific await context management. ```csharp public static void SafeFireAndForget( this Task task, ConfigureAwaitOptions configureAwaitOptions, Action? onException = null) ``` ```csharp task.SafeFireAndForget(ConfigureAwaitOptions.SuppressThrowing); ``` -------------------------------- ### Conditional Configuration by Environment Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Configures asynchronous operations based on the application's environment (Development, Staging, Production). Each environment can have distinct exception handling strategies. ```csharp public static class ServiceConfiguration { public static void Configure(EnvironmentType environment) { switch (environment) { case EnvironmentType.Development: ConfigureDevelopment(); break; case EnvironmentType.Staging: ConfigureStaging(); break; case EnvironmentType.Production: ConfigureProduction(); break; } } private static void ConfigureDevelopment() { SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: true); SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { Debug.WriteLine($"Exception: {ex}"); Debugger.Break(); // Stop debugger }); } private static void ConfigureStaging() { SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { Logger.Warn($"Exception: {ex.Message}"); AnalyticsService.LogException(ex, "staging"); }); } private static void ConfigureProduction() { SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { Logger.Error($"Unhandled exception: {ex.Message}", ex); RemoteLogging.SendAsync(ex).SafeFireAndForget(); }); } } ``` -------------------------------- ### Configuration Scenario: Feature-Specific Exception Handling Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Shows how to override or supplement global exception handling for a specific feature or asynchronous operation. ```csharp try { await SomeFeatureAsync(); } catch (Exception ex) { Console.WriteLine("Handling feature-specific error."); // Specific handling for this feature } ``` -------------------------------- ### ICommand.Execute(object?) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Synchronously initiates command execution without awaiting its completion, often referred to as 'fire and forget'. Exceptions are managed via an `onException` callback. ```APIDOC ## ICommand.Execute(object?) ### Description Synchronously initiates command execution without awaiting completion (fire and forget). ### Method `void ICommand.Execute(object? parameter)` ### Remarks - Uses `SafeFireAndForget` internally - Exceptions are handled by `onException` callback - Parameter is validated against TExecute type ### Throws - `InvalidCommandParameterException`: If parameter type doesn't match TExecute ``` -------------------------------- ### ICommand.Execute Implementation Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Provides a synchronous 'fire and forget' execution of the command, suitable for scenarios where awaiting the asynchronous operation is not required. Exceptions are managed by the onException callback, and the parameter is validated against the TExecute type. ```csharp void ICommand.Execute(object? parameter) ``` -------------------------------- ### AsyncValueCommand Constructor (No Parameters) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Concrete implementation of AsyncValueCommand with no execute or canExecute parameters. Use this when the command does not require any input parameters for execution or can-execute checks. ```csharp public class AsyncValueCommand : BaseAsyncValueCommand, IAsyncValueCommand { public AsyncValueCommand( Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) } ``` -------------------------------- ### ViewModel with FilterCommand (With Can-Execute) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Shows a ViewModel implementing a FilterCommand using AsyncValueCommand. It includes a CanFilter method to control execution based on busy state and filter input, and demonstrates yielding with Task.Delay(0) for large datasets. ```csharp public class ViewModel { private bool _isBusy; public IAsyncValueCommand FilterCommand { get; } public ViewModel() { FilterCommand = new AsyncValueCommand( execute: FilterAsync, canExecute: CanFilter ); } private bool CanFilter(string filter) { return !_isBusy && !string.IsNullOrEmpty(filter); } private async ValueTask FilterAsync(string filter) { _isBusy = true; try { // Filtering logic - often synchronous var results = GetFiltered(filter); // Only await if necessary if (results.Count > 1000) await Task.Delay(0); // Yield if large dataset } finally { _isBusy = false; FilterCommand.RaiseCanExecuteChanged(); } } private List GetFiltered(string filter) => new(); } ``` -------------------------------- ### ViewModel with ProcessCommand (With Parameter) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Illustrates a ViewModel using AsyncValueCommand to process a given count. It shows both asynchronous execution with await and fire-and-forget execution using Execute(int). ```csharp public class ViewModel { public IAsyncValueCommand ProcessCommand { get; } public ViewModel() { ProcessCommand = new AsyncValueCommand( execute: ProcessAsync ); } private async ValueTask ProcessAsync(int count) { // Quick operations often complete synchronously for (int i = 0; i < count; i++) { // Process } // Only await if needed var random = new Random(); if (random.Next(10) > 9) await Task.Delay(100); } } // Usage await processCommand.ExecuteAsync(10); processCommand.Execute(10); // Fire and forget ``` -------------------------------- ### AsyncCommand with Parameter Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md This pattern demonstrates how to pass parameters to an asynchronous command's execution method. It supports both direct execution and asynchronous execution with parameters. ```csharp public class ViewModel { public IAsyncCommand SearchCommand { get; } public ViewModel() { SearchCommand = new AsyncCommand( execute: SearchAsync ); } private async Task SearchAsync(string query) { // Perform search await Task.Delay(500); } } // Usage searchCommand.Execute("search term"); await searchCommand.ExecuteAsync("search term"); ``` -------------------------------- ### Configure Production Exception Handling with Crash Reporting and Notifications Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Sets up a comprehensive production exception handler that logs to a file, reports critical errors to a remote service, and notifies the user of critical issues. ```csharp public class App { public static void ConfigureAsync() { SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { // Log to local file LogToFile(ex); // Send to remote service if (IsNetworkAvailable()) CrashReporter.ReportAsync(ex).SafeFireAndForget(); // Show user notification for critical errors if (IsCritical(ex)) UserNotificationService.ShowError("An error occurred"); }); } private static bool IsCritical(Exception ex) => ex is not (IOException or TimeoutException); } ``` -------------------------------- ### SafeFireAndForget (Task with ConfigureAwaitOptions) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Safely executes a Task on .NET 8.0+ using ConfigureAwaitOptions for fine-grained behavior control. This method allows for specific await behavior configuration. ```APIDOC ## SafeFireAndForget (Task with ConfigureAwaitOptions) ### Description Safely executes a Task on .NET 8.0+ using `ConfigureAwaitOptions` for fine-grained behavior control. This method is useful for managing how the asynchronous operation resumes after awaiting, offering options like suppressing exceptions or continuing on the captured context. ### Availability .NET 8.0 and higher ### Method Signature ```csharp public static void SafeFireAndForget(this Task task, ConfigureAwaitOptions configureAwaitOptions, Action? onException = null) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **task** (Task) - Required - The Task to execute. - **configureAwaitOptions** (ConfigureAwaitOptions) - Required - Options controlling await behavior (None, SuppressThrowing, ContinueOnCapturedContext, ForceYielding). - **onException** (Action?) - Optional - Exception callback. Defaults to null. ``` -------------------------------- ### WeakEventManager with Action and Action Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Shows how to use WeakEventManager with Action and Action delegates for event handling. ```csharp var eventManager = new WeakEventManager(); // Subscribe with Action eventManager.Subscribe(myObject, "MyAction", () => { Console.WriteLine("Action executed."); }); // Subscribe with Action eventManager.Subscribe(myObject, "MyActionT", (int value) => { Console.WriteLine($"Action executed with value: {value}"); }); ``` -------------------------------- ### AsyncCommand with exception handling Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Illustrates how to handle exceptions that occur within an AsyncCommand's execution. ```csharp public class MyViewModel : ViewModelBase { public IAsyncCommand DoWorkCommand { get; } public MyViewModel() { DoWorkCommand = new AsyncCommand(DoWorkAsync, OnError); } private async Task DoWorkAsync() { await Task.Delay(1000); throw new InvalidOperationException("Work failed."); } private void OnError(Exception ex) { Console.WriteLine($"Command error: {ex.Message}"); } } ``` -------------------------------- ### IAsyncCommand Interface Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Supports different parameter types for execution and can-execute evaluation. ```APIDOC ## IAsyncCommand Interface ### Description Async command interface supporting different parameter types for execution and can-execute evaluation. ### Type Parameters | Parameter | Description | |-----------|-------------| | TExecute | Type of parameter for Execute/ExecuteAsync | | TCanExecute | Type of parameter for CanExecute evaluation | ### Methods #### CanExecute(TCanExecute) ```csharp bool CanExecute(TCanExecute parameter) ``` Determines whether the command can execute with the given parameter. **Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | parameter | TCanExecute | Parameter to evaluate | **Return:** bool — true if command can execute, false otherwise ``` -------------------------------- ### AsyncValueCommand Constructor Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Constructs a command with distinct parameter types for execution and can-execute logic. This provides flexibility when different data types are needed for performing the action versus checking its feasibility. ```csharp public class AsyncValueCommand : BaseAsyncValueCommand, IAsyncValueCommand { public AsyncValueCommand( Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) { // ... constructor implementation ... } } ``` -------------------------------- ### Incorrect Production Use of Initialize Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Demonstrates the incorrect use of SafeFireAndForget's Initialize method in a production environment, which can lead to application crashes due to unhandled exceptions. ```csharp // ❌ WRONG - will crash production app if any task throws public class App { public static void Main() { SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: true); // If any SafeFireAndForget task throws, application crashes // with no way to catch or handle the exception } } ``` -------------------------------- ### AsyncCommand with parameter Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Demonstrates an AsyncCommand that accepts a parameter of a specific type. ```csharp public class MyViewModel : ViewModelBase { public IAsyncCommand ProcessItemCommand { get; } public MyViewModel() { ProcessItemCommand = new AsyncCommand(ProcessItemAsync); } private async Task ProcessItemAsync(string item) { await Task.Delay(1000); Console.WriteLine($"Processing item: {item}"); } } ``` -------------------------------- ### Feature-Specific Exception Handling Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Demonstrates how to provide a custom exception handler for a specific asynchronous command, allowing for targeted error management within a feature. ```csharp public class SyncService { public SyncService() { // Feature uses custom exception handler _syncCommand = new AsyncCommand( execute: SyncAsync, onException: HandleSyncException ); } private void HandleSyncException(Exception ex) { Logger.Warn($"Sync failed: {ex.Message}"); // Could also fall back to global handler // by not catching and letting it propagate } private async Task SyncAsync() { // Sync logic } } ``` -------------------------------- ### Initialize SafeFireAndForget Global Behavior Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/SafeFireAndForgetExtensions.md Initializes the global behavior for SafeFireAndForget extensions. Use the `shouldAlwaysRethrowException` parameter for debugging purposes only, as it can crash the application. ```csharp public static void Initialize(bool shouldAlwaysRethrowException = false) ``` ```csharp SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: false); ``` -------------------------------- ### ICommand Interface Implementation Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Details the implementation of the standard `ICommand` interface for synchronous execution and condition checking, providing fire-and-forget behavior and parameter validation. ```APIDOC ## Inherited Methods from ICommand All AsyncCommand variants implement `System.Windows.Input.ICommand`. ### Execute(object? parameter) Synchronously initiates command execution without awaiting completion (fire and forget). **Remarks:** - Uses `SafeFireAndForget` internally. - Exceptions are handled by `onException` callback. - Parameter is validated against TExecute type. **Throws:** - `InvalidCommandParameterException`: If parameter type doesn't match TExecute. ### CanExecute(object? parameter) Determines if command can execute. **Remarks:** - Parameter is validated against TCanExecute type. - If TCanExecute is nullable, null parameter is allowed. - If TCanExecute is non-nullable reference type, null is allowed. - If TCanExecute is non-nullable value type, null throws. **Throws:** - `InvalidCommandParameterException`: If parameter type doesn't match TCanExecute. ``` -------------------------------- ### Basic Usage of SafeFireAndForget with ValueTask Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices/README.md Shows how to use SafeFireAndForget with an async ValueTask method. This allows the method to run asynchronously without blocking the calling thread, with error logging via an exception handler. ```csharp void HandleButtonTapped(object sender, EventArgs e) { // Allows the async ValueTask method to safely run on a different thread while the calling thread continues, not awaiting its completion // onException: If an Exception is thrown, print it to the Console ExampleValueTaskMethod().SafeFireAndForget(onException: ex => Console.WriteLine(ex)); // HandleButtonTapped continues execution here while `ExampleAsyncMethod()` is running on a different thread // ... } async ValueTask ExampleValueTaskMethod() { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(1000); } ``` -------------------------------- ### AsyncCommand with can-execute logic Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Shows how to implement can-execute logic for an AsyncCommand to control its execution state. ```csharp public class MyViewModel : ViewModelBase { private bool _canExecute = true; public IAsyncCommand SaveCommand { get; } public MyViewModel() { SaveCommand = new AsyncCommand(SaveAsync, CanExecuteSave); } private Task SaveAsync() { _canExecute = false; // Save logic... _canExecute = true; return Task.CompletedTask; } private bool CanExecuteSave() { return _canExecute; } } ``` -------------------------------- ### Using WeakEventManager with Action Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices/README.md Demonstrates how to implement an event using `Action` with a `WeakEventManager` to prevent memory leaks. This pattern is useful for decoupling event publishers and subscribers. ```csharp readonly WeakEventManager _weakActionEventManager = new WeakEventManager(); public event Action ActionEvent { add => _weakActionEventManager.AddEventHandler(value); remove => _weakActionEventManager.RemoveEventHandler(value); } void OnActionEvent(string message) => _weakActionEventManager.RaiseEvent(message, nameof(ActionEvent)); ``` -------------------------------- ### AsyncValueCommand Constructor Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Defines a command that accepts a typed parameter for its execute method. The canExecute predicate defaults to always returning true. Handles exceptions via an optional Action and allows control over context continuation. ```csharp public class AsyncValueCommand : BaseAsyncValueCommand, IAsyncValueCommand { public AsyncValueCommand( Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) { // ... constructor implementation ... } } ``` -------------------------------- ### AsyncValueCommand Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt Reference for the AsyncValueCommand module, covering 3 interface types, 3 class variants with constructors, 4 usage patterns, and guidance on ValueTask optimization. ```APIDOC ## AsyncValueCommand ### Description An optimized version of `AsyncCommand` that leverages `ValueTask` for improved performance in scenarios where the asynchronous operation might complete synchronously. ### Interfaces - `IAsyncValueCommand` - `IAsyncValueCommand` - `IAsyncValueCommand` ### Classes - `AsyncValueCommand` - `AsyncValueCommand` - `AsyncValueCommand` Each class includes constructors for initialization. ### Usage Patterns Details 4 usage patterns, including specific guidance on optimizing performance using `ValueTask` for command execution. ``` -------------------------------- ### SafeFireAndForgetExtensions Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/_COMPLETION_SUMMARY.txt Documentation for the SafeFireAndForgetExtensions module, which provides 8 method variants for safe fire-and-forget asynchronous operations. It includes parameter tables, return documentation, and behavior details. ```APIDOC ## SafeFireAndForgetExtensions ### Description Provides extension methods for safely executing asynchronous operations without explicitly awaiting them, preventing unhandled exceptions. ### Methods This module offers 8 method variants for various scenarios, including: - Methods for `Task` and `ValueTask`. - Overloads for different `ConfigureAwait` options. - Support for `CancellationToken`. ### Parameters Each method variant includes detailed parameter documentation, specifying name, type, and description. ### Return Documentation Methods typically return `void` as they are fire-and-forget, but exceptions are handled internally. ### Exception Flow Details on how exceptions are caught and logged or handled to prevent application crashes. ``` -------------------------------- ### ViewModel with RefreshCommand (No Parameters) Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncValueCommand.md Demonstrates a ViewModel using AsyncValueCommand for a refresh operation that might complete synchronously or asynchronously. The command is executed using Execute(null) for fire-and-forget behavior. ```csharp public class ViewModel { public IAsyncValueCommand RefreshCommand { get; } public ViewModel() { RefreshCommand = new AsyncValueCommand( execute: RefreshDataAsync, onException: ex => Debug.WriteLine($"Refresh failed: {ex}") ); } private async ValueTask RefreshDataAsync() { var random = new Random(); if (random.Next(10) > 9) await Task.Delay(1000); // Load data - many times completes synchronously } } // Usage viewModel.RefreshCommand.Execute(null); // Fire and forget ``` -------------------------------- ### AsyncCommand() - No Parameters Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/api-reference/AsyncCommand.md Concrete implementation of IAsyncCommand for commands that do not take parameters. ```APIDOC ## AsyncCommand Class ### AsyncCommand() — No Parameters ```csharp public class AsyncCommand : BaseAsyncCommand, IAsyncCommand { public AsyncCommand( Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) } ``` Command with no execute or canExecute parameters. **Constructor Parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | execute | Func | — | Function returning Task to execute; throws if null | | canExecute | Func? | null | Function determining if command can execute; if null, always returns true | | onException | Action? | null | Exception handler for Task failures | | continueOnCapturedContext | bool | false | If true, resume on captured context | **Return:** AsyncCommand instance **Throws:** - ArgumentNullException: If `execute` is null **Public Methods:** #### ExecuteAsync ```csharp public Task ExecuteAsync() ``` Executes the command without parameters. **Return:** Task representing the command execution **Example:** ```csharp var command = new AsyncCommand( execute: async () => { await Task.Delay(1000); Console.WriteLine("Done"); } ); // Using ExecuteAsync await command.ExecuteAsync(); // Using ICommand.Execute (fires and forgets) command.Execute(null); ``` ``` -------------------------------- ### Fire-and-forget basic usage Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Demonstrates the fundamental pattern for fire-and-forget asynchronous operations. ```csharp await Task.Run(async () => { await Task.Delay(1000); Console.WriteLine("Fire-and-forget operation completed."); }).ConfigureAwait(false); ``` -------------------------------- ### AsyncCommand Generic Constructor with Execute and CanExecute Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Initializes an AsyncCommand that accepts a parameter of type TExecute and a predicate for enabling/disabling the command. The predicate can also be asynchronous. ```csharp var command = new AsyncCommand( async (parameter) => { await Task.Delay(100); Console.WriteLine($"Executing with: {parameter}"); }, (parameter) => { return !string.IsNullOrEmpty(parameter); } ); ``` -------------------------------- ### AsyncCommand Constructor with TExecute, Object CanExecute, and Exception Handling Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices.MVVM/README.md Constructor for AsyncCommand with a generic execute type and an object type for can-execute, including optional exception handling and context control. ```csharp public AsyncCommand(Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) ``` -------------------------------- ### WeakEventManager RaiseEvent Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Illustrates raising events using the WeakEventManager. Supports various overloads to accommodate different event signature requirements. ```csharp // Non-generic weakEventManager.RaiseEvent(sender, EventArgs.Empty); // Generic weakEventManagerT.RaiseEvent(sender, eventArgs); ``` -------------------------------- ### WeakEventManager with EventHandler Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Demonstrates using WeakEventManager with a standard EventHandler delegate. ```csharp var eventManager = new WeakEventManager(); // Subscribe to an event eventManager.Subscribe(myObject, "MyEvent", (sender, args) => { Console.WriteLine("Event received."); }); // Later, when myObject is garbage collected, the subscription is automatically removed. ``` -------------------------------- ### Configure Exception Handling for Development and Production Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Configures exception handling based on the build environment. In DEBUG, all exceptions are rethrown and logged to the debug output; in production, exceptions are logged to a file. ```csharp public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); #if DEBUG // During development, make all exceptions visible SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: true); SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { Debug.WriteLine($"🔴 Fire-and-forget exception: {ex}"); }); #else // Production: normal behavior with logging SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => { Logger.Error("Fire-and-forget task failed", ex); }); #endif } } ``` -------------------------------- ### Initialize SafeFireAndForget for Debugging Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/configuration.md Configures SafeFireAndForget to rethrow exceptions during development for easier debugging. This should not be used in production. ```csharp public class App { public static void Main() { #if DEBUG // Enable exception rethrow for debugging SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: true); #else // Production: use default behavior (suppress exceptions) SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: false); #endif } } ``` -------------------------------- ### AsyncValueCommand Constructor with Generic Execute and Object CanExecute Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/src/AsyncAwaitBestPractices.MVVM/README.md Constructor for AsyncValueCommand with a generic execute function and an object-based can-execute function. ```csharp public AsyncValueCommand(Func execute, Func? canExecute = null, Action? onException = null, bool continueOnCapturedContext = false) ``` -------------------------------- ### AsyncValueCommand Generic Constructor with Execute and CanExecute Source: https://github.com/thecodetraveler/asyncawaitbestpractices/blob/main/_autodocs/MANIFEST.md Initializes an AsyncValueCommand with execution logic and a predicate to determine if the command can be executed. The predicate can be synchronous or asynchronous. ```csharp var valueCommand = new AsyncValueCommand( async (parameter) => { await Task.Delay(50); return parameter.Length; }, (parameter) => { return !string.IsNullOrEmpty(parameter); } ); ```