即使我认为我对事件链发生了100%肯定并且它们在相关位置受到try / catch的保护,但它并没有捕获事件链中的“更高”事件,并最终跳转到
private void CoreApplication_UnhandledErrorDetected(object sender,UnhandledErrorDetectedEventArgs ex)
我不明白为什么“更高”的try / catch没有捕获这个异常?
可能因为:
>它来自我的类构造函数调用的私有异步void方法?
>当我在我的viewmodelLocator中创建DataService时,它是在我创建服务时生成的,因为我正在使用MVVMLight?
无论如何都要从CoreApplication_UnhandledErrorDetected显示一个消息对话框?我已经研究了一段时间了,无法找到解决方案,因为我能做到这一点.这是一个错误,说这是不允许的.
我还添加了UnhandledException事件,但是没有被触发.
处理应用程序启动时抛出的异常的最佳方法是什么?
更新1:
我以为我会提供更多细节/代码,因为它仍然没有排序.
我实际上正在使用IOC / DI来加密/解密数据.加密类本身(EncryptionService)位于主应用程序中并实现了一个接口(IEncryptionService).
在我的DataService类第一次在AppShellviewmodel的构造函数中注入时创建了一个EncryptionService对象:
AppShellviewmodel
public class AppShellviewmodel { public AppShellviewmodel(IDataservice data) { .... } }
DataService的:
internal class DataService : IDataService { public DataService() { this.myExternalService = new MyExternalService(new EncryptionService()); } }
MyExternalService
internal sealed class MyExternalService { public class MyExternalService(IEncryptionService encryptionService) { this.MyPcl = MyPCL.Instance(encryptionService); } internal MyPCL MyPcl {get; set;} }
如您所见,当IDataService注入我的AppShellviewmodel类时,它会创建DataService类,而后者将创建我的新EncryptionService ojbect(基于IEncryptionService)并将其传递给MyExternalService类.
在MyExternalService的构造函数中,它通过调用静态方法(即Instance)创建MyPCL的单个对象,并传递在DataService中创建并传递给MyExternalService的EncryptionService对象.
如下所示,我在MyPCL的构造函数中读取了我的设置.一旦创建了单例对象,就会发生这种情况.它读取设置,然后尝试使用从我的应用程序传递的EncryptionService对象解密数据,并实现IEncryptionService.
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); } } }
现在在我的主应用程序中,EncryptionService使用Windows.Security.Cryptography.DataProtection,我有2个函数.正在进行异步调用的加密和解密. Decrypt函数定义如下:
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)); }
好吧,我认为上述内容虽然简化,但却代表了它的要点.
当它试图通过调用来解密调节数据时:
IBuffer decryptedBuffer = await provider.UnprotectAsync(data);
它是抛出错误的地方,但是如何抓住它并显示出错的地方并采取特定的行动?
我现在已经删除了所有错误处理程序,我希望你们中的一个会告诉我我需要把它放在哪里,因为DataService,MyExternalPcl和MyPCL中的每个函数都有错误处理,它仍然被轰炸并转到CoreApplication_UnhandledErrorDetected
谢谢.
更新2:
好吧,它需要相当多的麻烦才能最终找到正确的方法来解决这个问题,但Henk确实让我朝着正确的方向前进.
我的第一个问题,与我的问题中描述的不同,我使用了Protect和Unprotect的同步功能.这同样适用于我的加密/解密功能.我更改了它们以使用Protect和Unprotect的异步功能,并将Decrypt和Encrypt都修改为DecryptAsync / EncryptAsync并确保它们返回Task.
这可能听起来像一个小东西,但这必须修复或它导致我的应用程序锁定/挂起.
我根据这篇文章中的建议更改了下一部分Catch an exception thrown by an async method,(谢谢Henk!)是我从构造函数中调用异步方法的方法.
而不是调用我的ReadSettingsData方法,这是一个虚拟的void方法,因为我可以从我的构造函数中调用ReadSettings,我直接调用了ReadSetting,但如下所示:
public MyPCL(IEncryptionService encryptionService) { this._encryptionService = encryptionService; ReadSettingsData().Wait(); }
注意.Wait().完成后,我终于能够捕获异常并将其推回到我的事件链中,一直回到我的应用程序并显示一条消息并采取适当的操作.
由于这是我们的应用程序的一个严重错误,并且永远不会发生,我确保引入一个特定的异常,即EncryptionServiceException,它被捕获在ReadSettings中并相应地被抛回.
由于我没有在任何其他地方放置任何try / catch,它被从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. }); }
希望这可以帮助.
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。