β±οΈ Timeouts = Application Reliability
Long-running operations need timeouts. Cancellation tokens implement proper timeouts.
π Timeout Implementation
// Basic Timeout public async TaskGetDataWithTimeoutAsync() { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); try { return await GetExternalDataAsync(cts.Token); } catch (OperationCanceledException) { return "Request timed out"; } } // Timeout with Retry public async Task GetDataWithRetryAsync() { int retryCount = 0; while (retryCount < 3) { using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); try { return await GetDataAsync(cts.Token); } catch (OperationCanceledException) { retryCount++; if (retryCount >= 3) throw new TimeoutException("Operation timed out after retries"); } } throw new TimeoutException(); } // Custom Timeout Strategy public class TimeoutStrategy { public async Task ExecuteWithTimeoutAsync ( Func > operation, TimeSpan timeout, Action onTimeout = null) { using var cts = new CancellationTokenSource(timeout); var task = operation(cts.Token); try { return await task; } catch (OperationCanceledException) { onTimeout?.Invoke(); throw new TimeoutException($"Operation timed out after {timeout.TotalSeconds} seconds"); } } }
π― Advanced Patterns
// Race with Timeout public async TaskRaceWithTimeoutAsync ( Func > operation, TimeSpan timeout, T defaultValue = default) { using var cts = new CancellationTokenSource(timeout); var task = operation(cts.Token); var completed = await Task.WhenAny(task, Task.Delay(timeout)); if (completed == task) { return await task; } return defaultValue; } // Cooperative Cancellation public async Task ProcessAsync(CancellationToken cancellationToken) { for (int i = 0; i < 100; i++) { cancellationToken.ThrowIfCancellationRequested(); await Task.Delay(100, cancellationToken); // Process item } } // Timeout with Fallback public async Task GetDataWithFallbackAsync() { try { return await ExecuteWithTimeoutAsync( GetExternalDataAsync, TimeSpan.FromSeconds(5), () => LogTimeout() ); } catch (TimeoutException) { return GetCachedData(); } } // Configurable Timeout Service public class TimeoutService { private readonly ILogger _logger; private readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30); public async Task ExecuteAsync ( Func > operation, TimeSpan? timeout = null) { timeout ??= _defaultTimeout; using var cts = new CancellationTokenSource(timeout.Value); try { return await operation(cts.Token); } catch (OperationCanceledException) { _logger.LogWarning("Operation timed out after {Timeout}", timeout); throw new TimeoutException(); } } }
π‘ Timeout Tips
- Set appropriate timeout values
- Use cancellation tokens
- Handle timeout exceptions
- Log timeout events
- Provide fallback mechanisms
Timeouts are essential for application reliability. They prevent operations from hanging indefinitely.
