
即使我认为我对事件链发生了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. });} 希望这可以帮助.
解决方法 正如Henk提到的,每个异步方法都应该处理自己的异常.如果您想显示异步方法中有关抛出异常的一些信息,您应该在UI线程上调用消息对话框,如下所示:
async voID showMessageDialogMethod() { MessageDialog dialog = new MessageDialog("Sample message"); await dialog.ShowAsync(); }await dispatcher.RunAsync(CoredispatcherPriority.High,() => showMessageDialogMethod()); 总结 以上是内存溢出为你收集整理的c# – 在UWP中处理未处理的异常 – Windows 10全部内容,希望文章能够帮你解决c# – 在UWP中处理未处理的异常 – Windows 10所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)