防止在 Dart 中并发访问相同数据

Nai*_*rou 1 dart flutter

我正在尝试在 Dart (Flutter) 中创建文件缓存,其中文件仅下载一次,然后缓存以供将来的请求。(是的,我知道有这方面的现有软件包,但我的需求更具体。)

问题是,如果我在同一页面上有两个小部件尝试显示相同的图像,它们都会同时发出相同的请求,下载文件两次。

我尝试将缓存变成单例,分发其自身的单个实例,但这似乎没有效果:

class FileCache {
  final _fileList = List<File>();
  static FileCache _instance;

  factory FileCache() {
    if (_instance == null) {
      _instance = FileCache._internal();
    }
    return _instance;
  }

  FileCache._internal();

  bool add(File file) {
    if (_fileList.contains(file)) {
      return false;
    }
    _fileList.add(file);
    return true;
  }

  void remove(File file) {
    _fileList.remove(file);
  }
}
Run Code Online (Sandbox Code Playgroud)

我确实看到了另一个执行同步的包(此处),但查看 Dart 代码我不知道它是如何强制同步访问的。

在 Dart 中,如何强制为此目的连续访问特定的类或成员变量?

jam*_*lin 6

Flutter UI 在单个隔离区中运行。内存不会在隔离之间共享(因此得名),因此您无需担心并行操作(就像多核系统上的多个线程一样)。但是,您确实需要担心并发操作,这些操作在执行产生时可能会交错await

这意味着您不需要特殊的原子原语。您可以在下载文件时设置一个标志,以避免再次下载。

您不在Future任何地方使用 s,因此您的代码(如图所示)没有被中断的地方。但是,您也没有显示实际下载文件的代码,并且可能那里存在异步。你可以这样做:

final pendingDownloads = <String, Future<void>>{};
Future<void> downloadFile(String url) {
  if (pendingDownloads.containsKey(url)) {
    return pendingDownloads[url];
  }

  Future<void> downloadFileInternal() async {
    final request = await HttpClient().getUrl(...);
    ...
  }

  pendingDownloads[url] = downloadFileInternal();
  return pendingDownloads[url];
}

Run Code Online (Sandbox Code Playgroud)