gpt4 book ai didi

c# - 在UWP中处理未处理的异常-Windows 10

转载 作者:行者123 更新时间:2023-11-30 12:41:26 25 4
gpt4 key购买 nike

我的UWP应用执行的第一步是检查包含数据的文件是否可用。如果是这样,它将尝试解密此数据并继续进行下一步,但是如果加密的文件已被修改或由于抛出错误而损坏,我将尝试显示一个带有相关信息的消息对话框。

甚至以为我对事件链的发生有100%的把握,并且它们在相关位置受try/catch的保护,它没有抓住事件链中“较高”的事件,最终跳到

private void CoreApplication_UnhandledErrorDetected(object sender,
UnhandledErrorDetectedEventArgs ex)


我不明白为什么“较高”的 try/catch没有抓住这个 exception

可能是因为:


它来自我的类​​ private async void调用的 constructor方法吗?
它是在我的 ViewModelLocator中创建DataService时生成的,就像我使用MVVMLight一样在其中创建服务的地方?


反正有显示 CoreApplication_UnhandledErrorDetected的消息对话框吗?我已经研究了一段时间,但找不到解决方法,因为我该怎么做。抛出错误,表明不允许这样做。

我还添加了 UnhandledException事件,但是没有被触发。

处理应用程序启动时引发的异常的最佳方法是什么?

更新1:

我以为我会提供更多详细信息/代码,因为它仍未排序。

我实际上是使用 IOC / DI加密/解密数据。加密类本身( EncryptionService)在主应用程序中,并实现一个接口( IEncryptionService)。

EncryptionService对象是在将我的 DataService类首次注入 AppShellViewModel的构造函数中时创建的:

AppShellViewModel

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


数据服务:

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的构造函数中,它通过调用静态方法(即 MyPCL)创建 Instance的单例对象,并传递在 EncryptionService中创建并传递给 DataServiceMyExternalService对象。

如下所示,我在 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个函数。进行异步调用的加密和解密。解密功能定义如下:

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

谢谢。

UPDATE-2:

好的,这需要花很多时间弄乱才能最终找到正确的方法来解决此问题,但是Henk确实使我处于正确的方向。

我的第一个问题与问题中所描述的不同,我对保护和取消保护使用了同步功能。同样适用于我的加密/解密功能。我将它们都更改为使用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,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37415173/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com