Timeouts in Dart

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Dart is straightforward using Futures and the timeout method.

import 'dart:async';

Future<void> main() async {
  // For our example, suppose we're executing an external
  // call that returns its result after 2 seconds.
  // We use a Completer to simulate this asynchronous operation.
  final completer1 = Completer<String>();
  Timer(Duration(seconds: 2), () {
    completer1.complete('result 1');
  });

  // Here we implement a timeout using the `timeout` method on Future.
  // It will throw a TimeoutException if the operation takes longer than
  // the specified duration.
  try {
    final result = await completer1.future.timeout(Duration(seconds: 1));
    print(result);
  } on TimeoutException {
    print('timeout 1');
  }

  // If we allow a longer timeout of 3 seconds, then the operation
  // will complete successfully and we'll print the result.
  final completer2 = Completer<String>();
  Timer(Duration(seconds: 2), () {
    completer2.complete('result 2');
  });

  try {
    final result = await completer2.future.timeout(Duration(seconds: 3));
    print(result);
  } on TimeoutException {
    print('timeout 2');
  }
}

Running this program shows the first operation timing out and the second succeeding.

$ dart run timeouts.dart
timeout 1
result 2

In this Dart version:

  1. We use Future and Completer to simulate asynchronous operations instead of goroutines and channels.

  2. The timeout method on Future is used to implement timeouts, which throws a TimeoutException if the operation takes longer than specified.

  3. We use try-catch blocks to handle the timeout exceptions.

  4. The async-await syntax is used to work with Futures in a more readable way.

  5. The Timer class is used to delay the completion of our simulated asynchronous operations.

This example demonstrates how to implement timeouts for asynchronous operations in Dart, which is crucial for handling external resources or bounding execution time in your applications.