zer*_*ing 4 dart dart-isolates
我正在尝试使用dart隔离库来提高我的应用程序性能.
看下面的代码:
import 'dart:isolate';
import 'package:dbcrypt/dbcrypt.dart';
main() {
var pwConPort = new ReceivePort();
pwConPort.listen((data) {
print(data);
pwConPort.close();
}, onError: (err) {
print(err);
});
Isolate.spawn(generatePasswordConcurrency, pwConPort.sendPort);
}
void generatePasswordConcurrency(SendPort sendPort) {
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
String _generateHashPassword(String password) {
var regex = new RegExp(r'^.*(?=.{7,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$');
if (!regex.hasMatch(password)) {
throw new StateError('Errors');
}
return new DBCrypt().hashpw(password, new DBCrypt().gensalt());
}
Run Code Online (Sandbox Code Playgroud)
一切正常但我只能传递一个静态密码,或者更好地说,我不知道,如何动态传递一些东西.在这里你可以看到,密码是硬编码的,但我想传递一个变量.
void generatePasswordConcurrency(SendPort sendPort) {
sendPort.send(_generateHashPassword('Passsowr1222!'));
}
Run Code Online (Sandbox Code Playgroud)
如果方法_generateHashPassword将抛出错误,我该如何处理此错误?我尝试从ReceivePort捕获listen方法的错误
pwConPort.listen((data) {
print(data);
pwConPort.close();
}, onError: (err) {
print(err);
});
Run Code Online (Sandbox Code Playgroud)
但仍然有未处理的异常消息.
Observatory listening on http://127.0.0.1:51433
in ShutdownIsolate: Unhandled exception:
Bad state: Errors
#0 _generateHashPassword (file:///D:/Dart/samples/bin/isolate_error.dart:26:9)
#1 generatePasswordConcurrency (file:///D:/Dart/samples/bin/isolate_error.dart:19:40)
#2 _startIsolate.isolateStartHandler (dart:isolate-patch/isolate_patch.dart:221)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:124)
Run Code Online (Sandbox Code Playgroud)
结论我的问题:
如何将变量传递给隔离的被调用方法?
如何处理隔离错误?
首先,
隔离不是线程,它们是独立的进程,更像是fork()
一个线程
使用隔离的并发编程:与线程类似但不共享内存的独立工作者,仅通过消息进行通信.
因此,您无法访问与父进程相同的变量.这是飞镖队的一个选择,因为它是一种在js中编译你的飞镖代码时可用的机制.所以它需要在JS中成为可能
如何将变量传递给隔离的被调用方法?
要做到这一点,你需要看到ReceivePort()
一种单向通信方式,所以要以两种方式传递变量,你需要两种.
所以在你的主要过程中:
pwConPort.listen((data) {
if (isolateSendPort == null && data is SendPort) {
isolateSendPort = data; // Receive the communication object of the isolate
isolateSendPort.send("Passsowr1222!");
} else {
print("Generated password: ${data}");
pwConPort.close();
}
}, onError: (err) {
print("SendPortError: ${err}");
});
});
Run Code Online (Sandbox Code Playgroud)
在你隔离入口点:
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
// code ....
});
Run Code Online (Sandbox Code Playgroud)
注意:请注意您发送的消息.一个进程和另一个进程之间发送的消息需要遵守一些规则
消息的内容可以是:原始值(null,num,bool,double,String),SendPort的实例,以及其元素是其中任何一个的列表和映射.列表和地图也允许循环.
如何处理隔离错误?
隔离得到一个方法来监听由孤立发送的throw throw错误:addErrorListner 这是一个有用的函数.
但是!这种方法并没有在每个版本中实现,因此您需要在其他版本中执行此操作.
我选择的方式是在入口点函数中发送2个SendPort:
一个用于沟通
一个是错误的.
所以spawn函数看起来像:
Isolate.spawn(generatePasswordConcurrency, [pwConPort.sendPort, errorPort.sendPort])
Run Code Online (Sandbox Code Playgroud)
和generatePasswordConcurrency
:
void generatePasswordConcurrency(List<SendPort> commList) {
var sendPort = commList[0];
var errorPort = commList[1];
var isolateConPort = new ReceivePort();
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
try {
sendPort.send(_generateHashPassword(data));
} catch (e) {
errorPort.send("error: ${e.toString()}");
}
});
}
Run Code Online (Sandbox Code Playgroud)
这里是完整的代码:
import 'dart:isolate';
import 'package:dbcrypt/dbcrypt.dart';
main() {
var pwConPort = new ReceivePort();
var errorPort = new ReceivePort();
SendPort isolateSendPort = null;
Isolate.spawn(generatePasswordConcurrency, [pwConPort.sendPort, errorPort.sendPort])
.then((Isolate pcs) {
errorPort.listen((err) {
print("Error: ${err}");
pwConPort.close();
errorPort.close();
});
print(pcs);
pwConPort.listen((data) {
if (isolateSendPort == null && data is SendPort) {
isolateSendPort = data;
isolateSendPort.send("Passsowr1222!");
} else {
print("Generated password: ${data}");
pwConPort.close();
errorPort.close();
//pcs.kill();
}
}, onError: (err) {
print("SendPortError: ${err}");
});
});
}
void generatePasswordConcurrency(List<SendPort> commList) {
var sendPort = commList[0];
var errorPort = commList[1];
var isolateConPort = new ReceivePort();
sendPort.send(isolateConPort.sendPort);
isolateConPort.listen((data) {
try {
sendPort.send(_generateHashPassword(data));
} catch (e) {
errorPort.send("error: ${e.toString()}");
}
});
}
String _generateHashPassword(String password) {
var regex = new RegExp(r'^.*(?=.{7,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).*$');
if (!regex.hasMatch(password)) {
throw new StateError('Errors');
}
return new DBCrypt().hashpw(password, new DBCrypt().gensalt());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1491 次 |
最近记录: |