Dart 如何传递消息以隔离和处理错误
我正在尝试使用dart隔离库来提高我的应用程序性能 请看以下代码:Dart 如何传递消息以隔离和处理错误,dart,dart-isolates,Dart,Dart Isolates,我正在尝试使用dart隔离库来提高我的应用程序性能 请看以下代码: 导入“省道:隔离”; 导入“package:dbcrypt/dbcrypt.dart”; main(){ var pwConPort=new ReceivePort(); pwConPort.listen((数据){ 打印(数据); pwConPort.close(); },onError:(错误){ 打印(错误); }); 隔离.spawn(generatePasswordConcurrency,pwConPort.sendP
导入“省道:隔离”;
导入“package:dbcrypt/dbcrypt.dart”;
main(){
var pwConPort=new ReceivePort();
pwConPort.listen((数据){
打印(数据);
pwConPort.close();
},onError:(错误){
打印(错误);
});
隔离.spawn(generatePasswordConcurrency,pwConPort.sendPort);
}
void generatePasswordConcurrency(发送端口发送端口){
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
字符串_generateHashPassword(字符串密码){
var regex=new RegExp(r'^..*(=.{7,})(?=.\d)(?=.[a-z])(?=.[a-z])(?=.[a-z])(?=.[^a-zA-Z0-9]).$);
如果(!regex.hasMatch(密码)){
抛出新StateError(“错误”);
}
返回new DBCrypt().hashpw(密码,new DBCrypt().gensalt());
}
一切正常,但我只能传递一个静态密码,或者更好地说,我不知道如何动态传递某些东西。在这里您可以看到,密码是硬编码的,但我想传递一个变量,例如
void生成密码并发(发送端口发送端口){
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
如果generateHashPassword方法将抛出错误,我如何处理此错误?我试图从ReceivePort捕获侦听方法的错误
pwConPort.listen((数据){
打印(数据);
pwConPort.close();
},onError:(错误){
打印(错误);
});
但仍然收到未处理的异常消息
天文台监听http://127.0.0.1:51433
在关闭隔离中:未处理的异常:
错误状态:错误
#0\u生成密码(file:///D:/Dart/samples/bin/isolate_error.dart:26:9)
#1生成密码并发(file:///D:/Dart/samples/bin/isolate_error.dart:19:40)
#2 _startIsolate.isolateStartHandler(省道:隔离补片/隔离补片。省道:221)
#3 RawReceivePortImpl.handleMessage(dart:isolate patch/isolate_patch.dart:124)
结论我的问题:
如何将变量传递给隔离上被调用的方法?如何处理隔离上的错误 首先, 隔离不是线程,它们是独立进程,更像是
fork()
,而不是线程
使用隔离的并发编程:
与线程类似但不共享内存的独立工作线程,仅通过
信息
因此,您不能访问与父进程相同的变量。这是dart团队的选择,因为在js中编译dart代码时,这是一种可用的机制。所以它需要在JS中成为可能
如何在隔离时将变量传递给被调用的方法?
要做到这一点,您需要像单向通信方式一样查看ReceivePort()
,所以要以两种方式传递变量,您需要两种方式
因此,您需要了解主要流程:
pwConPort.listen((数据){
如果(isolateSendPort==null&&数据为发送端口){
isolateSendPort=data;//接收隔离的通信对象
发送(“Passsowr1222!”);
}否则{
打印(“生成的密码:${data}”);
pwConPort.close();
}
},onError:(错误){
打印(“发送端口错误:${err}”);
});
});
在中,隔离入口点:
sendPort.send(IsolatConport.sendPort);
IsolatConport.listen((数据){
//代码。。。。
});
注意:注意你发送的信息。在一个进程和另一个进程之间发送消息需要遵守一些规则
消息的内容可以是:原始值(null、num、bool、,
双精度,字符串),发送端口实例,以及列表和映射
元素是这些元素中的任意一个。列表和地图也允许使用
循环的
如何处理隔离上的错误?
隔离获取一个方法来侦听隔离发送的抛出错误:
这是一个有用的函数
但是这种方法并不是在每一个板形中都实现的,所以您需要在其他板形中实现
我选择的方式是在入口点函数中发送2个SendPort:
- 一个用于通信
- 一个是错误
隔离.spawn(generatePasswordConcurrency,[pwConPort.sendPort,errorPort.sendPort])
以及生成密码并发性:
void generatePasswordConcurrency(列表commList){
var sendPort=commList[0];
var errorPort=commList[1];
var isolateConPort=new ReceivePort();
sendPort.send(IsolatConport.sendPort);
IsolatConport.listen((数据){
试一试{
sendPort.send(_generateHashPassword(数据));
}捕获(e){
errorPort.send(“错误:${e.toString()}”);
}
});
}
以下是完整的代码:
导入“省道:隔离”;
导入“package:dbcrypt/dbcrypt.dart”;
main(){
var pwConPort=new ReceivePort();
var errorPort=new ReceivePort();
发送端口isolateSendPort=null;
隔离.spawn(generatePasswordConcurrency,[pwConPort.sendPort,errorPort.sendPort])
.然后((隔离pcs){
errorPort.listen((错误){
打印(“错误:${err}”);
pwConPort.close();
errorPort.close();
});
印刷品(件);
pwConPort.listen((数据){
如果(isolateSendPort==null&&数据为发送端口){
isolateSendPort=数据;
发送(“Passsowr1222!”);
}否则{
打印(“生成的密码:${data}”);
pwConPort.close();
errorPort.close();
//pcs.kill();
}
},onError:(错误){
打印(“发送端口错误:${err}”);
});
});
}
void generatePasswordConcurrency(列表commList){
var sendPort=commList[0];
var errorPort=commList[1];
var isolateConPort=new ReceivePort();
sendPort.send(IsolatConport.sendPort