Dart ResourceHandle
last modified April 4, 2025
The ResourceHandle class in Dart provides a way to manage resources
that need explicit cleanup. It's useful for file handles, network connections,
and other disposable resources.
ResourceHandle ensures resources are properly released when no longer needed. It helps prevent resource leaks and follows the RAII (Resource Acquisition Is Initialization) pattern.
Basic Definition
ResourceHandle is a wrapper for resources that require cleanup.
It manages the resource lifecycle and ensures proper disposal when the handle
goes out of scope.
Key features include automatic disposal, manual release control, and error handling. It's particularly useful for scarce or expensive resources.
Basic ResourceHandle Usage
This example shows basic resource management using ResourceHandle.
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
}
We create a ResourceHandle for a File object with a custom dispose function. The file will be deleted automatically when the handle is no longer needed.
$ dart main.dart # File is created and automatically deleted
Manual Resource Release
This example demonstrates manual control over resource disposal.
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();
});
}
We create a ResourceHandle for a network socket and manually dispose it after use. This gives precise control over resource lifetime when needed.
$ dart main.dart # Socket is connected, used, and properly closed
Error Handling with Resources
This example shows error handling in resource management.
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
}
The ResourceHandle ensures the database file is cleaned up even when an error occurs during operation. This prevents resource leaks in error scenarios.
$ dart main.dart Error occurred: Exception: Database operation failed Cleaning up database file
Multiple Resources Management
This example demonstrates managing multiple resources together.
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
}
We manage multiple resources as a group, ensuring coordinated cleanup. This is useful when working with related resources that should be released together.
$ dart main.dart # All files and directory are created and cleaned up
Custom Resource Types
This example shows using ResourceHandle with custom resource types.
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://localhost/mydb'),
dispose: (db) => db.close(),
);
// Use the database connection
print('Using database: ${dbHandle.value.connectionString}');
// Connection will be automatically closed
}
We create a ResourceHandle for a custom DatabaseConnection class. The handle ensures proper connection closure, demonstrating the pattern's flexibility.
$ dart main.dart Connected to postgres://localhost/mydb Using database: postgres://localhost/mydb Closed connection to postgres://localhost/mydb
Best Practices
- Always dispose: Ensure all resources have proper dispose handlers
- Use groups: Manage related resources together when possible
- Error safety: Design dispose handlers to be exception-safe
- Document: Clearly document resource ownership and lifetimes
Source
Dart ResourceHandle Documentation
This tutorial covered Dart's ResourceHandle class with practical examples showing basic usage, error handling, and resource management patterns.
Author
List all Dart tutorials.