How to send one message and receive multiple data asynchronously returned?
Closed this issue · 2 comments
In my example, I want to call IsolateManager.sendMessage once and receive one hundred data translated to the main thread from the isolate.
I found through debugging that IsolateManagerController calls sendResult multiple times, but IsolateManager.stream can only receive one data.
I want to know whether it's possible to achieve the desired effect without modifying isolate_manager project code, which means passing in one number and getting 100 numbers out.
import 'package:isolate_manager/isolate_manager.dart';
@pragma('vm:entry-point')
void findPrimeNumbersIsolateFunction(dynamic params) {
final channel = IsolateManagerController<int, int>(params);
findPrimeNumbersTransform(channel.onIsolateMessage).listen((message) {
channel.sendResult(message);
});
}
Stream<int> findPrimeNumbersTransform(Stream<int> numStream) =>
numStream.asyncExpand((event) {
return findPrimeNumbers(event * 10, 100);
});
Stream<int> findPrimeNumbers(int from, int count) async* {
int num = from;
int found = 0;
while (found < count) {
if (isPrime(num)) {
yield num;
found++;
}
num++;
}
}
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
int i = 5;
while (i * i <= n) {
if (n % i == 0 || n % (i + 2) == 0) return false;
i += 6;
}
return true;
}
final primeIsolate = IsolateManager.createOwnIsolate(
findPrimeNumbersIsolateFunction,
);
void initIsolate() {
primeIsolate.stream.listen((event) {
currentPrime = event;
if (!primeController.isClosed) {
primeController.add((index++, event));
}
});
numController.stream.listen((event) {
primeIsolate.sendMessage(event);
});
}
Hi @AoEiuV020
If you want to get multiple values in a single sendMessage
, you can use the callback
parameter like this:
await primeIsolate.sendMessage(10, callback: (value) {
// Assume that this value is a flag or a final result that lets us know it is the last value.
// Only this value will be sent to the `stream`.
//
// If this line is not set, this `sendMessage` will be stuck forever.
if (value == -1) return true;
return false;
});
And we need to modify the findPrimeNumbers
a little bit to add a flag -1
:
Stream<int> findPrimeNumbers(int from, int count) async* {
int num = from;
int found = 0;
while (found < count) {
if (isPrime(num)) {
yield num;
found++;
}
num++;
}
// To let the `callback` know this is the last value.
yield -1;
}
With this way, the primeIsolate.stream
seems useless.
Feel free to re-open if the issue still persists.