【发布时间】:2022-01-10 06:03:29
【问题描述】:
我有这个程序用来学习 Dart 的异步编程。
import 'dart:io';
Future<int> sumStream(Stream<int> stream) async {
var sum = 0;
await for (final value in stream) {
print('consuming event $value');
sum += value;
}
return sum;
}
Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
sleep(const Duration(milliseconds: 400));
print('publishing event $i');
yield i;
}
}
Future<void> main() async {
var stream = countStream(10);
var sum = sumStream(stream);
print('working...');
sleep(const Duration(milliseconds: 500));
print('working...');
sleep(const Duration(milliseconds: 500));
print('working...');
sleep(const Duration(milliseconds: 500));
print(await sum); // 55
}
输出:
working...
working...
working...
publishing event 1
consuming event 1
publishing event 2
consuming event 2
publishing event 3
consuming event 3
publishing event 4
consuming event 4
publishing event 5
consuming event 5
publishing event 6
consuming event 6
publishing event 7
consuming event 7
publishing event 8
consuming event 8
publishing event 9
consuming event 9
publishing event 10
consuming event 10
55
在上面的代码中,对于sumStream() 的结果,我选择不立即使用await,因为我想做一些额外的工作,而sumStream() 正忙于从提供的流中消费事件。所以我的期望是sumStream() 会在main() 运行时立即开始运行。我希望输出看起来像下面的文本。我希望文本 working... 与出版商 countStream() 和消费者 sumStream() 的其他打印输出交错。
working...
publishing event 1
consuming event 1
publishing event 2
consuming event 2
publishing event 3
consuming event 3
working...
publishing event 4
consuming event 4
publishing event 5
consuming event 5
publishing event 6
working...
consuming event 6
publishing event 7
consuming event 7
publishing event 8
consuming event 8
publishing event 9
consuming event 9
publishing event 10
consuming event 10
55
这是因为 Dart 是单线程的,因此它不能同时运行 main()、countStream() 和 sumStream()?
如果是这样,我该如何更改我的程序,以便 sumStream() 与 main() 并行运行(使其成为多线程)?
【问题讨论】:
-
您不会获得您期望的并发性,因为在事件队列被处理之前不会执行流,并且在您使用
await或退出main之前不会发生这种情况。是的,每个 Dart 隔离都是单线程的,所以如果你想要并行(而不仅仅是并发)操作,你需要生成一个单独的隔离。 -
@jamesdlin 感谢您的解释。在您的回复和对程序的更多思考之后,我明白为什么它的行为不像我预期的那样。我的问题也不是很清楚,但我想你还是明白了。我真正想要的是在
countStream()处于睡眠状态时运行main(),并在main()处于睡眠状态时运行countStream()。原来sleep()阻塞了队列,在我按照下面@mmcdon20 的建议用await Future.delayed(const Duration(milliseconds: 500));替换它之后,它就像我喜欢的那样工作。
标签: dart async-await