2016-05-24 28 views
3

私のUWPアプリケーションが最初に行う処理は、データを含むファイルが利用可能かどうかを確認することです。そうであれば、このデータを復号化して次のステップに進みますが、暗号化されたファイルが調整されているか、エラーを投げて破損している場合は、関連情報とともにメッセージダイアログを表示しようとしています。UWPで処理されない例外を処理する - Windows 10

はしても、私が発生したイベントの連鎖を100%確信していると、彼らは、関連する場所でtry/catchにより保護されていること、それは一連の出来事に「高い」ものをキャッチしていないと思ったし、それが最終的に

にジャンプ
private void CoreApplication_UnhandledErrorDetected(object sender, 
UnhandledErrorDetectedEventArgs ex) 

なぜ「上位」try/catchがこれをキャッチしていないのか分かりません。exception

でしているので:

  • それは私のクラスconstructorから呼び出さprivate async void方法から来るの?

  • MVVMLightを使用しているため、サービスを作成しているViewModelLocatorに自分のDataServiceを作成すると生成されますか?

CoreApplication_UnhandledErrorDetectedからメッセージダイアログを表示するにはどうしますか?私はしばらくそれを研究してきましたし、私がこれをやる方法として解決策を見つけることができません。これは許可されていないというエラーが表示されます。

私もUnhandledExceptionイベントを追加しましたが、それはトリガーされていません。

アプリケーションの起動時にスローされる例外を処理する最善の方法は何ですか?

アップデート-1:

私はそれがまだソートされていないとして、私は詳細/コードを提供しようと思いました。

私は実際にIOC/DIを使用してデータを暗号化/復号化しています。暗号化クラス自体(EncryptionService)はメインアプリにあり、インターフェイス(IEncryptionService)を実装しています。

AppShellViewModel

public class AppShellViewModel 
{ 
    public AppShellViewModel(IDataservice data) 
    { 
     .... 
    } 
} 

のDataService:

internal class DataService : IDataService 
{ 
    public DataService() 
    { 
     this.myExternalService = new MyExternalService(new EncryptionService()); 
    } 
} 
DataServiceクラスが最初に作成されたとき、それが AppShellViewModelのコンストラクタに注入されたときに

EncryptionServiceオブジェクトが作成されます

MyExternalService

internal sealed class MyExternalService 
{ 
    public class MyExternalService(IEncryptionService encryptionService) 
    { 
    this.MyPcl = MyPCL.Instance(encryptionService); 
    } 

    internal MyPCL MyPcl {get; set;} 
} 

IDataServiceが私のAppShellViewModelのクラスに注入されたときに、見ることができるように、それは順番に(IEncryptionServiceに基づいて)私の新しいEncryptionService ojbectを作成し、それを渡しますDataServiceクラスを作成しますMyExternalServiceクラスに変更します。 MyExternalServiceのコンストラクタにおいて

、それは静的メソッドすなわちInstance呼び出すことにより、MyPCLのシングルトンオブジェクトを作成し、DataServiceで作成され、MyExternalServiceに渡されたEncryptionServiceオブジェクトを渡します。

以下に示すように、私はMyPCLのコンストラクタの設定を読みます。これは、シングルトンオブジェクトが作成されると起こります。設定を読み取り、を実装しているEncryptionServiceオブジェクトを使用してデータを復号化しようとします。

public class MyPCL 
{ 
    private readonly IEncryptionService _encryptionService; 

    public MyPCL(IEncryptionService encryptionService) 
    { 
     this._encryptionService = encryptionService; 
     ReadSettingsData(); 
    } 

    public static MyPCL Instance(IEncryptionService encryptionService) 
    { 
     if (null == _instance) 
     { 
     lock (SingletonLock) 
     { 
      if (null == _instance) 
      { 
      _instance = new MyPCL(this._encryptionService); 
      } 
     } 
    } 
    return _instance; 
    } 

    private async void ReadSettingsData() 
    { 
    await ReadSettings(); 
    } 

    private async Task ReadSettings() 
    { 
    IFolder folder = FileSystem.Current.LocalStorage; 
    IFile file = folder.GetFileAsync("MyFile.txt").Result; 

    string data = await file.ReadAllTextAsync().Result; 
    if (!string.IsEmptyOrNull(data)) 
    { 
     data = await this._encryptionService.DecryptAsync(data); 
    } 
    } 
} 

は今、私のメインアプリで、EncryptionServiceWindows.Security.Cryptography.DataProtectionを使用していますし、私はそれに2つの機能を持っています。非同期呼び出しを行っている暗号化と復号化。復号化機能は、次のように定義されています。

public async Task<string> DecryptAsync(string encryptedText) 
{ 
    var provider = new DataProtectionProvider("LOCAL = user"); 

    IBuffer data = CryptographicBuffer.DecodeFromHexString(encryptedText); 
    IBuffer decryptedBuffer = await provider.UnprotectAsync(data); 

    return await Task.FromResult(CryptographicBuffer.ConvertBinaryToString 
     (BinaryStringEncoding.Utf8, decryptedBuffer)); 
} 

[OK]を上記のように定義しますが、それはその要点を表していると思います。

IBuffer decryptedBuffer = await provider.UnprotectAsync(data); 

それは結構ですが、私はそれをキャッチし、何かが間違っていたことを表示し、特定のアクションを実行する方法にエラーがスローされますどこにある:それは呼び出すことで鍛えたデータを復号化しようとした

? ?

私はすべてのエラーハンドラを削除しました。DataService、MyExternalPcl、およびMyPCLのすべての関数がエラー処理を行い、まだ爆発してどこに行き渡ったのか正確に伝える必要があります〜CoreApplication_UnhandledErrorDetected

ありがとうございます。

UPDATE-2:

[OK]を、それが最終的にこれを処理する正しい方法を見つけるためにいじりのかなり必要ですが、ヘンクは正しい方向に私を入れていました。

私の最初の問題は、私の質問で説明したのとは異なり、私は保護と保護解除の同期機能を使用していました。私の暗号化/復号化機能にも同じことが適用されます。私はProtectとUnprotectの非同期機能を使用するように両方を変更し、DecryptAsync/EncryptAsyncにDecryptとEncryptの両方を変更し、Taskを返すようにしました。

小さなもののように聞こえるかもしれませんが、これを修正するか、アプリがロック/ハングする原因となりました。

このポストで提案された内容に基づいて変更された次の部分Catch an exception thrown by an async method(Thank you Henk!)は、コンストラクタからの非同期メソッドの呼び出し方法です。

の代わりに、私は私のコンストラクタからReadSettingsを呼び出すことができるように導入されたダミーvoid方法であった私のReadSettingsDataメソッドを呼び出して、次のように、私は直接ReadSettingと呼ばれるが、:

public MyPCL(IEncryptionService encryptionService) 
{ 
    this._encryptionService = encryptionService; 
    ReadSettingsData().Wait(); 
} 

お知らせ.Wait()。いったん終了すると、私は最終的に例外をキャッチし、私のアプリに戻ってイベントのチェーンをプッシュし、メッセージを表示して適切な処置をとることができました。

これはアプリにとって重大なエラーであり、決して発生しないはずです。具体的な例外、つまりEncryptionServiceExceptionが導入されていることを確認しました。これはReadSettingsにキャッチされ、それに応じてスローされます。

はどこにも置かれていないので、MyExternalPclライブラリからアプリにプッシュバックされていますが、通常の例外ではなくAggregateExceptionとして返されますが、これはこの記事で簡単に処理できます: How to: Handle Exceptions Thrown by Tasksが、ここでは、コアの抜粋です:

catch (AggregateException ae) 
{ 

    ae.Handle((x) => 
    { 
     if (x is UnauthorizedAccessException) // This we know how to handle. 
     { 
      Console.WriteLine("You do not have permission to access 
           all folders in this path."); 
      Console.WriteLine("See your network administrator or try 
           another path."); 
      return true; 
     } 
     return false; // Let anything else stop the application. 
    }); 

} 

は、この情報がお役に立てば幸いです。

+0

@HenkHolterman。私は.Wait()を追加しました。それは間違いなく改善されました。私は今私が扱うことができる集約例外を生成し、私のUnhandledExceptionも引き起こされていると私は何をすべきかを決定することができます。私は明日より多くの小切手をして確認しますが、とにかくあなたが正しいかもしれないと思います。ありがとう。 – Thierry

+0

@HenkHolterman私はちょうどこの問題を解決するためのアップデートを投稿しましたが、昨日ロックをかけている間に暗号機能を非同期に変更して問題を解決しました。 .wait()が理想的でない場合は、別の推奨解決策がありますか?私は非同期ボイドを再導入しようとしますが、何が起こるかを見てみましょう。しかし、別の解決策があれば、それを分かち合うことができたら本当に感謝します。ありがとう。 – Thierry

+0

@HenkHolterman私はちょうどそれを試みたが、私は正方形に戻っている。エラーがスローされ、飲み込まれ、コードが継続して、他のエラーがスローされ、「UnhandledException」イベントが発生しましたが、これは現在の動作です。私も試しました。他の2つのデバイス、つまりphone&sp3に移動してください(期待通りに動作するようです)。 – Thierry

答えて

1

Henkが言及するように、すべての非同期メソッドは独自の例外を処理する必要があります。

あなたは以下のようなUIスレッド上でメッセージダイアログを呼び出す必要がスローされた例外についての非同期メソッドからいくつかの情報を表示したい場合:私はあなたが正しいかもしれないと思う

async void showMessageDialogMethod() 
    { 
     MessageDialog dialog = new MessageDialog("Sample message"); 
     await dialog.ShowAsync(); 
    } 


await Dispatcher.RunAsync(CoreDispatcherPriority.High, 
         () => showMessageDialogMethod()); 
+0

あなたの言っていることが分かりません。私は少し曖昧だったかもしれないので、私の質問にもっと多くの情報を追加しました。多分、これが助けになるでしょう。私はこれをどこで扱うべきかを具体的に教えてくれるでしょうか? – Thierry

+0

ここで詳しい情報をありがとうございました。私は仕事を終えて、それを助けようとすると、それを通ります。 –

+0

ダニエルありがとう、本当にありがとう! – Thierry