ZetCode

Dart ResourceHandle

最后修改于 2025 年 4 月 4 日

Dart 中的 ResourceHandle 类提供了一种管理需要显式清理的资源的方法。它适用于文件句柄、网络连接和其他可处置资源。

ResourceHandle 确保在不再需要资源时正确释放它们。它有助于防止资源泄露,并遵循 RAII(资源获取即初始化)模式。

基本定义

ResourceHandle 是需要清理的资源的包装器。它管理资源生命周期,并确保在句柄超出作用域时正确处置。

主要功能包括自动处置、手动释放控制和错误处理。它对于稀缺或昂贵的资源尤其有用。

基本的 ResourceHandle 用法

此示例展示了使用 ResourceHandle 进行的基本资源管理。

main.dart
import 'dart:io';

void main() {
  // Create a resource handle for a temporary file
  var fileHandle = ResourceHandle<File>(
    File('temp.txt'),
    dispose: (file) => file.delete(),
  );

  // Use the resource
  fileHandle.value.writeAsStringSync('Hello, ResourceHandle!');
  
  // Resource is automatically disposed when handle goes out of scope
}

我们为具有自定义处置函数的 File 对象创建了一个 ResourceHandle。当不再需要句柄时,文件将自动删除。

$ dart main.dart
# File is created and automatically deleted

手动释放资源

此示例演示了对资源处置的手动控制。

main.dart
import 'dart:io';

void main() {
  var socketHandle = ResourceHandle<Socket>(
    Socket.connect('example.com', 80).then((socket) => socket),
    dispose: (socket) => socket.close(),
  );

  // Use the resource
  socketHandle.value.then((socket) {
    socket.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n');
    
    // Manually release when done
    socketHandle.dispose();
  });
}

我们为网络套接字创建了一个 ResourceHandle,并在使用后手动处置它。这在需要时提供了对资源生命周期的精确控制。

$ dart main.dart
# Socket is connected, used, and properly closed

资源错误处理

此示例展示了资源管理中的错误处理。

main.dart
import 'dart:io';

void main() {
  try {
    var dbHandle = ResourceHandle<File>(
      File('database.db'),
      dispose: (file) {
        print('Cleaning up database file');
        file.deleteSync();
      },
    );

    // Simulate an error
    throw Exception('Database operation failed');
  } catch (e) {
    print('Error occurred: $e');
  }
  // Handle ensures cleanup happens even on error
}

即使在操作过程中发生错误,ResourceHandle 也能确保数据库文件得到清理。这可以防止在错误场景下的资源泄露。

$ dart main.dart
Error occurred: Exception: Database operation failed
Cleaning up database file

多个资源管理

此示例演示了对多个资源的组合管理。

main.dart
import 'dart:io';

void main() {
  var resources = ResourceHandle.group([
    ResourceHandle<File>(
      File('log1.txt'),
      dispose: (file) => file.delete(),
    ),
    ResourceHandle<File>(
      File('log2.txt'),
      dispose: (file) => file.delete(),
    ),
    ResourceHandle<Directory>(
      Directory('temp'),
      dispose: (dir) => dir.delete(recursive: true),
    ),
  ]);

  // Use resources
  resources[0].value.writeAsStringSync('Log entry 1');
  resources[1].value.writeAsStringSync('Log entry 2');
  
  // All resources will be disposed together
}

我们将多个资源作为一个组进行管理,确保协调清理。这在处理应一起释放的相关资源时非常有用。

$ dart main.dart
# All files and directory are created and cleaned up

自定义资源类型

此示例展示了将 ResourceHandle 与自定义资源类型一起使用。

main.dart
class DatabaseConnection {
  final String connectionString;
  
  DatabaseConnection(this.connectionString) {
    print('Connected to $connectionString');
  }
  
  void close() {
    print('Closed connection to $connectionString');
  }
}

void main() {
  var dbHandle = ResourceHandle<DatabaseConnection>(
    DatabaseConnection('postgres:///mydb'),
    dispose: (db) => db.close(),
  );

  // Use the database connection
  print('Using database: ${dbHandle.value.connectionString}');
  
  // Connection will be automatically closed
}

我们为自定义 DatabaseConnection 类创建了一个 ResourceHandle。该句柄确保正确关闭连接,展示了该模式的灵活性。

$ dart main.dart
Connected to postgres:///mydb
Using database: postgres:///mydb
Closed connection to postgres:///mydb

最佳实践

来源

Dart ResourceHandle 文档

本教程介绍了 Dart 的 ResourceHandle 类,并通过实际示例展示了基本用法、错误处理和资源管理模式。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 Dart 教程