我的UWP应用程序首先会检查是否有包含数据的文件可用。如果有,它将尝试解密这些数据并继续下一步,但如果加密文件已被篡改或损坏,则我正在尝试通过抛出错误显示相关信息的消息对话框。
尽管我对事件链的发生顺序和它们在相关位置上受到try/catch保护的情况非常确定,但它没有捕获事件链中的“更高级别”问题,最终跳到了。
正如您所看到的,当
在
正如您下面所看到的,在
这里出现了错误,但我该如何捕获它并显示出某些事情出错了并采取特定的行动呢?
我已经删除了所有的错误处理程序,希望你们中的某一个能告诉我在哪里放置它,因为几乎每个函数在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!),我更改了从构造函数调用我的异步方法的方式。
我直接调用了ReadSetting而不是调用我的ReadSettingsData方法,该方法是一个虚拟的void方法,我可以从构造函数中调用ReadSettings。
注意
由于这是我们应用程序的关键错误,不应该发生,因此我确保引入了一个特定的异常,即EncryptionServiceException,并在ReadSettings中捕获并相应地抛出。
由于我没有在任何其他地方放置
希望这可以帮到您。
尽管我对事件链的发生顺序和它们在相关位置上受到try/catch保护的情况非常确定,但它没有捕获事件链中的“更高级别”问题,最终跳到了。
private void CoreApplication_UnhandledErrorDetected(object sender,
UnhandledErrorDetectedEventArgs ex)
我不明白为什么“高级”的try/catch无法捕获此异常?
可能是因为:
它来自于我在构造函数中调用的私有异步方法
private async void
?当我的DataService在ViewModelLocator中创建服务时生成,因为我使用了MVVMLight?
有没有办法从CoreApplication_UnhandledErrorDetected
显示消息对话框?我已经研究了一段时间,但找不到解决方案。它会抛出错误,称不允许这样做。
我还添加了UnhandledException
事件,但没有被触发。
处理应用程序启动时抛出的异常的最佳方法是什么?
更新-1:
我想提供更多细节/代码,因为问题仍未解决。
实际上,我正在使用IOC / DI加密/解密数据。加密类本身(EncryptionService)位于主应用程序中并实现接口(IEncryptionService)。
当第一次创建注入到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
对象(基于IEncryptionService
)并将其传递给MyExternalService
类。在
MyExternalService
的构造函数中,它通过调用静态方法即Instance
来创建MyPCL
的单例对象,并将在DataService
中创建并传递给MyExternalService
的EncryptionService
对象传递给它。正如您下面所看到的,在
MyPCL
的构造函数中读取设置。这是在创建单例对象后发生的。它读取设置,然后尝试使用从我的应用程序传递并实现IEncryptionService
的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);
}
}
}
现在在我的主应用程序中,EncryptionService
使用 Windows.Security.Cryptography.DataProtection
,并且我有两个函数。Encrypt 和 Decrypt 都是异步调用。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!),我更改了从构造函数调用我的异步方法的方式。
我直接调用了ReadSetting而不是调用我的ReadSettingsData方法,该方法是一个虚拟的void方法,我可以从构造函数中调用ReadSettings。
public MyPCL(IEncryptionService encryptionService)
{
this._encryptionService = encryptionService;
ReadSettingsData().Wait();
}
注意
.Wait()
。一旦完成,我终于能够捕获异常并将其推回到我的事件链中,一直返回到我的应用程序,并显示消息并采取适当的操作。由于这是我们应用程序的关键错误,不应该发生,因此我确保引入了一个特定的异常,即EncryptionServiceException,并在ReadSettings中捕获并相应地抛出。
由于我没有在任何其他地方放置
try/catch
,它从MyExternalPcl库被推回到我的应用程序,但它不是常规异常,而是作为AggregateException
返回,但可以按照本文处理: 如何: 处理任务引发的异常,以下是核心代码段: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.
});
}
希望这可以帮到您。
Debug
模式下它运行得很好,但当我切换到Release
模式并在手机上尝试时,我的应用程序就会卡住!!真气人!!为什么会有这种不一致性?? - Thierry