【发布时间】:2016-12-01 11:06:42
【问题描述】:
这是用户界面代码。正在尝试计算列表视图中显示的文件和文件夹的磁盘使用情况。
if (FileHelper.IsFolder(info))
{
UsageSummary usage = DiskUsage.GetTotalUsage(info.FullName).Result;
totalSize += usage.TotalSize;
}
else
{
totalSize += info.Length;
}
这里是 GetTotalUsage() 方法。这个想法是,如果可用,它应该返回一个缓存值。如果该值不可用,它将仅返回顶层文件的大小并启动另一个方法,该方法将从该点递归地下降目录树并创建缓存条目,以便下次我们访问该文件夹时,我们应该得到一个缓存的值。
async public static Task<UsageSummary> GetTotalUsage(string folder)
{
UsageSummary totalUsage = null;
if (!IsCached(folder, ref totalUsage))
{
// Not cached, get first-level usage
totalUsage = GetFileUsage(folder);
// Start async process to cache total usage of this folder
await AsyncCacheUsage(totalUsage);
}
// Was cached, or we got the first-level results.
return totalUsage;
}
最后一个方法是计算文件夹实际大小的递归函数的网关方法。
async private static Task AsyncCacheUsage(UsageSummary summary)
{
try
{
AccumulateChildFolders(summary.Folder, summary);
CacheResults(summary);
// Now we start a watch on the volume that
// can invalidate cache entries when changes occur.
_watcher.WatchVolume(summary.Folder);
}
catch (Exception ex)
{
Log.Error(ex, "CacheTotalUsage: {1}", ex.Message);
}
}
代码在调试器中似乎可以正常工作和表现。
但我的问题是,我这样做对吗?对于正在显示的文件夹中的每个子文件夹,GetTotalUsage 方法将被调用一次,许多 AsynchCacheUsage 实例在文件系统的所有下降的不同分支中都存在。这意味着我需要开始担心线程安全?所有代码都是静态的,包括访问一个静态字典,该字典缓存了我可能应该添加锁的用法。我还遗漏了其他任何陷阱吗?
当我真正的意思是出去做你的工作而不打扰我时,我调用“await AsyncCacheUsage”似乎很奇怪。
【问题讨论】:
-
我认为您应该收到
AsyncCacheUsage的警告。你,你是否选择忽略它? -
AsyncCacheUsage is doing anawait 中没有任何内容,因此它将阻塞其线程。AccumulateChildFolders可能也应该是异步的,但是您需要小心更新作为参数传递的对象(我假设您使用结果更新summary参数)因为这将在 之后更新函数已返回。最好使用返回值。 -
异步不是在上面的 GetTotalUsage 中开始的吗?这就是我打算开始的地方。我没有从编译器收到“您的方法将同步运行”警告。
标签: c# async-await task-parallel-library .net-4.5