我正在尝试在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);
}
}
我确实看到了另一个进行同步(here)的程序包,但是看着Dart代码,我不知道它是如何执行同步访问的。
如何在Dart中为此目的强制串行访问特定的类或成员变量?
答案 0 :(得分:1)
Flutter UI在单个隔离中运行。这意味着您不必担心并行操作(就像在多核系统上使用多个线程那样),但是您确实需要担心当执行await
时可以交错的并行操作
这意味着您不需要特殊的原子基元。您可以在下载文件时设置标记,以避免再次下载。
您不会在任何地方使用Future
,因此没有地方可以中断您的代码(如图所示)。但是,您也不会在实际下载文件的位置显示代码,并且大概在那里不同步。您可以执行以下操作:
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];
}