dart中实现子isolate的管理类,特适用于针对数据库的处理
dart中的isolate已经困扰我好几天了,主要项目需要,比如对数据库的处理,都放到一个单独的子isolate(子线程)中,优势在于,当数据库足够大时,对数据库的处理可能较为耗时,这时,只用dart的主isolate,可能会对其他逻辑的处理,造成阻塞。可能有人说,await、async不就可以异步实现吗,异步操作和子线程操作还是有很大区别的。这篇可以用作了解学习
最开始接触isolate时,主子isolate发送接收port,很容易绕晕,不过,结合一些网上资料,加上这个简单的demo,有助于理解,希望能帮到一些和我一样,因刚接触isolate而头疼的人。至少让我豁然开朗了,也看到了自己思维的局限性,不够扩散开来。
代码贴出如下,由于没用到什么插件,所以,不会对使用插件版本过度依赖,亲测,可本机直接$ dart run
运行,另外,这只是个demo,不涉及任何项目内容的东西,但你看明白了,应用起来会很迅速,特此记录。
import 'dart:isolate';
// 子 isolate 要执行的函数
void childIsolate(SendPort sendPort) async {
// 创建一个 ReceivePort 来接收主 isolate 发送的数据
ReceivePort receivePort = ReceivePort();
// 将 ReceivePort 的 SendPort 发送给主 isolate
sendPort.send(receivePort.sendPort);
await for (var message in receivePort) {
if (message is List && message.length > 3 && message[0] == 'insert') {
print("childIsolate cur received: $message");
SendPort responseSendPort = message[3];
String table = message[1];
String row = message[2];
String ret = await DBUtils().insert(table, row);
responseSendPort.send(ret);
} else {
print(": $message");
}
}
}
class IsolateService {
static Isolate? _isolate;
static SendPort? _childSendPort;
static final ReceivePort _receivePort = ReceivePort();
static Future<void> init() async {
_isolate = await Isolate.spawn(childIsolate, _receivePort.sendPort);
await for (var message in _receivePort) {
if (message is SendPort) {
_childSendPort = message;
break;
}
}
}
static Future<dynamic> sendAndReceive(dynamic message) async {
if (_childSendPort == null) {
throw Exception('childIsolate is not initialized. Call init() first.');
}
final responseReceivePort = ReceivePort();// 作为当前主调子一次的返回,一次处理完成后,需要close,下次再调时,再创建
_childSendPort!.send([...message, responseReceivePort.sendPort]);
try {
final response = await responseReceivePort.first;
print("mainIsolate has get the response fron childIsolate: $response");
responseReceivePort.close();
return response;
} catch (e) {
print('Error receiving response: $e');
return null;
}
}
static void dispose() {
_receivePort.close();
_isolate?.kill(priority: Isolate.immediate);
}
}
class DBUtils {
Future<String> insert(String table, String row) async {// 模拟耗时任务
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 100; j++) {
for (int k = 0; k < 100; k++) {}
}
}
return "ret from insert";
}
}
void main() async {
await IsolateService.init();
// 第一个场景
Future(() async {
final response1 = await IsolateService.sendAndReceive(['insert', 'table1', 'row1']);
print("Received response in first scenario: $response1");
});
// 第二个场景
Future(() async {
final response2 = await IsolateService.sendAndReceive(['insert', 'table2', 'row2']);
print("Received response in second scenario: $response2");
});
// 模拟程序结束时释放资源
await Future.delayed(Duration(seconds: 5));
IsolateService.dispose();
}