gpt4 book ai didi

如果等待未立即完成,Dart File.writeAsString() 方法不会写入文件

转载 作者:行者123 更新时间:2023-12-03 03:41:31 32 4
gpt4 key购买 nike

我有以下 Dart 代码,但其行为与我预期的不一样:

final File file = File("result.csv");

Future send(String message) async {
try {
await file.writeAsString(message + '\n',
mode: FileMode.append, flush: true);
} catch (e) {
print("Error: $e");
}
return await file.length();
}

main() async {
final futures = <Future>[];
for (int i = 0; i < 100; i++) {
futures.add(send("$i"));
}
for (int i = 0; i < 100; i++) {
print(await futures[i]);
}
}

我希望每次调用 await futures[i] 时都会写入文件在第二个循环中返回。然而,这似乎并没有发生。

对于从 0 到 99 的每个索引,文件应该包含一行。但它包含一行 99后跟一个空行。并且第二个循环中的打印调用总是打印相同的文件长度, 3 .

事件循环似乎以某种方式合并了调用,并且只实际执行了最后一个调用,即使我仍然在第二个循环中等待 100 个不同的 future 。

为什么会发生这种情况,我怎样才能让 future 在不立即等待的情况下运行(我真的只需要稍后等待,当所有对 send 的调用都已完成时)?

最佳答案

随着循环:

for (int i = 0; i < 100; i++) {
futures.add(send("$i"));
}

多个 send立即被调用,每个人同时打开并在文件中写入一个字符串:您有一个竞争条件,并且在最后只有一条消息被写入文件。

使用返回 future 的函数列表

使用闭包,可以实现用于文件访问的序列化版本,以避免竞争条件。

与其创建一个 future 列表,不如创建一个返回 future 的函数列表:
如果您在循环中调用并等待此类函数,则将按顺序访问共享文件资源:
import 'dart:io';

final File file = File("result.csv");

typedef Future SendFunction();

Future send(String message) async {
try {
await file.writeAsString(message + '\n',
mode: FileMode.append, flush: true);
} catch (e) {
print("Error: $e");
}
var l = await file.length();
return l;
}

main() async {

final futures = List<SendFunction>();
//final futures = <Future>[];

for (int i = 0; i < 100; i++) {
//futures.add(send("$i"));
futures.add(() => send("$i"));
}

for (int i = 0; i < 100; i++) {
print(await futures[i]());
//print(await futures[i]);
}
}

同步包

synchronized提供锁机制来防止并发访问异步代码。

在这种情况下,它可以用来避免并发访问 result.csv文件:
import 'dart:io';
import 'package:synchronized/synchronized.dart';

final File file = File("result.csv");
final lock = new Lock();

Future send(String message) async {
try {
await file.writeAsString(message + '\n',
mode: FileMode.append, flush: true);
} catch (e) {
print("Error: $e");
}
return await file.length();
}

main() async {
final futures = <Future>[];
for (int i = 0; i < 100; i++) {
futures.add(lock.synchronized(() => send("$i")));
}
for (int i = 0; i < 100; i++) {
print(await futures[i]);
}
}

关于如果等待未立即完成,Dart File.writeAsString() 方法不会写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54958346/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com