2016-05-31 4 views
1

つの質問:ログの正しい方法

  • 非同期メソッドの実装この実装でありますか?
  • これは、ファイルの削除中に表示される可能性のある例外を記録する正しい実装ですか?

    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); 
      } 
     } 

    } 
+2

「catch」句はどこですか? 'async/await'は、コードが同期コードのように動作することを意味します。つまり、例外を発生させます。このコードは、最初のエラー –

+1

でクラッシュするだけです。また、削除を実行するために 'Select'節を使用するのは非常に良い設計ではありません。 –

+0

@Panagiotis Kanavos私の考えは、私の結果クエリが列挙<タスク>を返し、その後、私はすべてのタスクの完了を待ってから、私は本当の例外が含まれているだけIAsyncActionエンティティを取り、それらをログに記録していました。しかし、ここに私の2つの脅しがあります。そのような実装は非同期ではなく、私はタスクがどちらかのエラーで終了するという前提でリレーします。 Msdnヘルプdoesnotここで明確に例外を指定しません。https://msdn.microsoft.com/en-us/library/windows/apps/br227201.aspx –

答えて

1

すべての削除は、同期の経験を与えて待たれますので、第2の実現は、ファイルを一つずつ削除します。したがって、最初の実装はより速いかもしれません。

適切な実装:

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ブロック、例外処理は、常に明確にコードで識別されるべきだと思います。

タスクを取得するには.Selectに注意してください。不要な非同期/待機を削除しました。

またはTask.WaitAll(results)を行うと、AggregateException

参照をキャッチもWhy doesn't await on Task.WhenAll throw an AggregateException?

0

ロギングが並列に行くことができます別のアプローチ。これはと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();