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

如果未立即完成等待,则Dart File.writeAsString()方法不会写入文件,dart,Dart,我有以下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 a

我有以下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]);
  }
}
final File File=File(“result.csv”);
未来发送(字符串消息)异步{
试一试{
等待文件.writeAsString(消息+'\n',
模式:FileMode.append,flush:true);
}捕获(e){
打印(“错误:$e”);
}
返回wait file.length();
}
main()异步{
最终期货=[];
对于(int i=0;i<100;i++){
期货。添加(发送(“$i”);
}
对于(int i=0;i<100;i++){
打印(等待期货[i]);
}
}
我希望在第二个循环中对
await futures[I]
的每次调用返回时,都能尽快写入该文件。然而,这似乎没有发生

文件应包含0到99之间每个索引的一行。但它包含一行
99
,后跟一个空行。第二个循环中的print调用总是打印相同的文件长度,
3

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

为什么会发生这种情况?我如何允许期货在不立即等待的情况下运行(我真的需要等到以后,当所有对
send
的调用都已发出时才等待)?

循环:

for (int i = 0; i < 100; i++) {
  futures.add(send("$i"));
}
同步包 提供锁定机制以防止对异步代码的并发访问

在这种情况下,它可用于避免并发访问
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:io';
导入“包:synchronized/synchronized.dart”;
最终文件=文件(“result.csv”);
最终锁=新锁();
未来发送(字符串消息)异步{
试一试{
等待文件.writeAsString(消息+'\n',
模式:FileMode.append,flush:true);
}捕获(e){
打印(“错误:$e”);
}
返回wait file.length();
}
main()异步{
最终期货=[];
对于(int i=0;i<100;i++){
futures.add(lock.synchronized(()=>send($i));
}
对于(int i=0;i<100;i++){
打印(等待期货[i]);
}
}

谢谢。我不知道Dart中可能会出现这样的同步问题,因为用户代码无法创建线程(在没有隔离的情况下)。我想这只是一个问题,因为
File.writeAsString()
本身不是用Dart编写的?我不能真正谈论Dart内部,但我认为不是。这种行为与以下事实有关:在不等待完成的情况下并发调用
send
futures.add(send($I))
)在不进行文件访问同步的情况下,尽快同时指示执行所有
send
。不需要同步,因为据我所知,文件系统本身会处理这些问题。我所期望的是无序写入,这在我的情况下是可以的。我创建了一个bug,看起来Dart团队认为可以在内部使用append的原子版本,这将解决此问题:
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]);
  }
}