2016-07-21 9 views
2

未処理の例外イベントのハンドラを作成しています。このハンドラは、例外をファイルにダンプし、さらに解析するためにサーバに送信します。今のところ私は例外をファイルに保存し、次回の実行時にそれを表示したいと考えています。ハンドラから私はこのような実装を持っている機能を、呼んでいる:未処理の例外ハンドラにファイルを非同期で書き込む

public async Task WriteDataAsync(string filename, string data) 
{ 
    var file = await this.storageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); 
    await FileIO.WriteTextAsync(file, data); 
} 

問題は、ファイルが存在しなかった場合、それが作成されますが、例外データがファイルに保存されていないということです。しかし、ファイルが存在する場合、データは適切に保存されます。この関数は、未処理例外の処理に使用されていない場合に機能します。
私はこの問題に関して2つの質問があります。

  1. このような状況では、どのような理由がありますか。私はasync/awaitメソッドが正常に動作するように動作する方法と関係がありますが、このコンテキストでは例外を処理する際に問題があると思います。
  2. このような状況でファイルに非同期で書き込む方法はありますか?この場合、同期機能を実行するための解決策が1つあります。

    public void WriteDataAsync(string filename, string data) 
    { 
        var fileTask = this.storageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting).AsTask(); 
        var writingToFileTask = FileIO.WriteTextAsync(fileTask.Result, data).AsTask(); 
        writingToFileTask.Wait(); 
    } 
    

    私は書き込みの前にファイルを作成することも考えました。ただし、データは再度ファイルに書き込まれませんでした。

+1

関連するすべてのコード、つまりイベントハンドラを表示できますか?データが書き込まれる前にアプリケーションが終了する可能性はありますか? – svick

答えて

0

その文脈で、このような行動の理由は何ですか。私は非同期/待機メソッドが動作する方法と関係していると思います。

あなたの推測は正しいです。 awaitメソッドを呼び出すと、asyncメソッドの呼び出し元に制御が返されます。このコンテキストでは、コントロールは最終的にWindowsランタイムに戻ります。通常、UnhandledExceptionイベントが発生すると、Windowsランタイムによってアプリケーションが終了します。そのため、非同期操作が完了する前にアプリが終了する可能性があります。そして、これはあなたが見た行動につながる可能性があります。

このような状況でファイルに非同期で書き込む他のソリューションはありますか?この場合、同期機能を実行するための解決策が1つあります。

このシナリオでは、通常、SuspendingDeferralまたはBackgroundTaskDeferralのような非同期操作の延期が必要です。しかし、UnhandledExceptionイベントにそのようなものはありません。この場合、あなたのソリューションは正しいです。これらの操作を同期させて、この問題を回避することができます。このブログ(Strategies for Handling Errors in your Windows Store Apps)を参照して、未処理の例外を処理することができます。また、このソリューションを使用します。

+0

問題について説明されている解決策以外の解決策が見つかりましたが、あなたの答えは私の質問を満たしています。 –

+0

@MaxiKingあなたが見つけた他の解決策は何ですか?私はまたそれについて興味がある。それが他人を助けることができるように共有してください。 –

+1

解決方法は、イベントハンドラの本体をtaskとAutoResetEvent.Set()に入れることでした。ハンドラ本体のAutoResetイベントWaitOne()に入りました。 –

0

私はあなたがFileMode.OpenOrCreateを使用することができると思う:

public async Task WriteDataAsync(string fileName, string data) 
    { 
     byte[] text = Encoding.Unicode.GetBytes(data); 

     using (var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write)) 
     { 
      await stream.WriteAsync(text, 0, text.Length); 
     }; 
    }