关于以下代码的两个问题:
是否正确实现了记录删除文件时可能出现的异常?
public static async Task DeleteFiles(StorageFolder folder, Regex mask, LoggingChannel logger)
{
var results = (from file in await folder.GetFilesAsync() where mask.IsMatch(file.Name) select file).Select(async f => await f.DeleteAsync());
await Task.WhenAll(results);
foreach (var failed in results.Where(r => r.Exception != null)) logger.LogMessage(failed.Exception.ToString(), LoggingLevel.Warning);
}
它更好(对吧?)方式:
public static async Task DeleteFiles(StorageFolder folder, Regex mask, LoggingChannel logger)
{
foreach(var f in (await folder.GetFilesAsync()).Where( f => mask.IsMatch(f.Name)))
{
try
{
await f.DeleteAsync();
}
catch(Exception ex)
{
logger.LogMessage(ex.ToString(), LoggingLevel.Warning);
}
}
}
答案 0 :(得分:1)
第二个实现将逐个删除文件,因为将等待每次删除以提供同步体验。所以第一次实现可能会更快。
正确实施:
public static async Task DeleteFilesAsync(StorageFolder folder, Regex mask, LoggingChannel logger)
{
var results = (from file in await folder.GetFilesAsync() where mask.IsMatch(file.Name) select file).Select(f => f.DeleteAsync());
try
{
await Task.WhenAll(results);
}
catch(Exception ex)
{
foreach (var failed in results.Where(r => r.Exception != null)) logger.LogMessage(failed.Exception.ToString(), LoggingLevel.Warning);
}
}
我认为应始终在代码中明确标识异常处理,因此尝试使用try / catch块。
记住。选择获取任务,我删除了不必要的异步/等待那里。
或执行Task.WaitAll(results)
并抓住AggregateException
另见Why doesn't await on Task.WhenAll throw an AggregateException?
答案 1 :(得分:0)
另一种可以并行进行日志记录的方法。这是使用rx和DataFlowBlock。
var actBlock = new ActionBlock<Task>(t => { var tsk = t.IsFaulted ? loggingTask : dummyTask; },new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = configurableValue
});
var obsr = actBlock.AsObserver();
FileDeletionTasks.ToObservable().Subscribe(t => obsr.OnNext(t), async ex => await loggingTask);
actBlock.Complete();