我正在使用Azure表存储作为存储机制.我可以将视图模型中的异常从视图模型中写入Azure表,但当我try 向App.cs上的未处理异常添加处理程序时,异常会记录在Debug Output窗口中,但不会存储在Azure表中.

这是我的Program.cs分:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                fonts.AddFont("SF-Pro-Text-Bold.otf", "SFProTextBold");
                fonts.AddFont("SF-Pro-Text-Regular.otf", "SFProTextRegular");
                fonts.AddFont("materialdesignicons-webfont.ttf", "MaterialDesignIcons");
            });

        builder.UseMauiApp<App>()
            .UseMauiCommunityToolkit()
            .RegisterDataServices()
            .RegisterViewModels()
            .RegisterViews();

        builder.Logging.AddSerilog();

        var storageConnectionString = "MY_CONNECTION_STRING";
        var tableName = "logs";

        Log.Logger = new LoggerConfiguration()
            .WriteTo.AzureTableStorage(connectionString: storageConnectionString, storageTableName: tableName)
            .WriteTo.Debug()
            .CreateLogger();

        return builder.Build();
    }
}

这是我的App.cs:

public partial class App : Application
    {
        private readonly ILogger<App>_logger;

        public App(ILogger<App> logger)
        {
            _logger = logger;
            InitializeComponent();
            AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
            MainPage = new AppShell();
        }

        private void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            var exception = (Exception)e.ExceptionObject;
            _logger.LogCritical(exception, exception.Message);
        }
    }
}

这是我要实现日志(log)记录的一个视图模型:

public class OnboardingViewModel : BaseViewModel
{
    private ILogger<OnboardingViewModel> _logger;

    public OnboardingViewModel(ILogger<OnboardingViewModel> logger)
    {
        _logger = logger;
    }

    private void OnSkipOnboardingCommand()
    {
        try
        {
            throw new Exception("Oops! Something went wrong.");
        }
        catch (Exception e)
        {
            _logger.LogError(e, e.Message);
        }
    }
}

当我try 这样做时,异常显示在输出窗口上,并保存到Azure表中:

enter image description here

但是,如果我将OnSkipOnboardCommand更改为:

private void OnSkipOnboardingCommand()
{
    throw new Exception("Oops! Unhandled Exception.");
}

我在App.cs号的HandleUnhandledException号收到了例外.异常仅记录到输出窗口中:

[0:] [07:38:43 FTL] Oops! Unhandled Exception.
System.Exception: Oops! Unhandled Exception.
   at MyApp.Mobile.ViewModels.OnboardingViewModel.OnSkipOnboardingCommand() in C:\Users\Developer\Development\MyApp\src\MyApp.Mobile\ViewModels\OnboardingViewModel.cs:line 74
   at Microsoft.Maui.Controls.Command.<>c__DisplayClass4_0.<.ctor>b__0(Object o) in D:\a\_work\1\s\src\Controls\src\Core\Command.cs:line 80
   at Microsoft.Maui.Controls.Command.Execute(Object parameter) in D:\a\_work\1\s\src\Controls\src\Core\Command.cs:line 123
   at Microsoft.Maui.Controls.TapGestureRecognizer.SendTapped(View sender, Func`2 getPosition) in D:\a\_work\1\s\src\Controls\src\Core\TapGestureRecognizer.cs:line 59
   at Microsoft.Maui.Controls.Platform.TapGestureHandler.OnTap(Int32 count, MotionEvent e) in D:\a\_work\1\s\src\Controls\src\Core\Platform\Android\TapGestureHandler.cs:line 69
   at Microsoft.Maui.Controls.Platform.InnerGestureListener.Android.Views.GestureDetector.IOnGestureListener.OnSingleTapUp(MotionEvent e) in D:\a\_work\1\s\src\Controls\src\Core\Platform\Android\InnerGestureListener.cs:line 157
   at Android.Views.GestureDetector.IOnGestureListenerInvoker.n_OnSingleTapUp_Landroid_view_MotionEvent_(IntPtr jnienv, IntPtr native__this, IntPtr native_e) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-33/mcw/Android.Views.GestureDetector.cs:line 711
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_Z(_JniMarshal_PPL_Z callback, IntPtr jnienv, IntPtr klazz, IntPtr p0) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 137
   at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 11969
   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualBooleanMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 164
   at Android.Views.GestureDetector.OnTouchEvent(MotionEvent ev) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-33/mcw/Android.Views.GestureDetector.cs:line 1639
   at Microsoft.Maui.Controls.Platform.TapAndPanGestureDetector.OnTouchEvent(MotionEvent ev) in D:\a\_work\1\s\src\Controls\src\Core\Platform\Android\TapAndPanGestureDetector.cs:line 36
   at Microsoft.Maui.Controls.Platform.GesturePlatformManager.OnTouchEvent(MotionEvent e) in D:\a\_work\1\s\src\Controls\src\Core\Platform\GestureManager\GesturePlatformManager.Android.cs:line 83
   at Microsoft.Maui.Controls.Platform.GesturePlatformManager.OnPlatformViewTouched(Object sender, TouchEventArgs e) in D:\a\_work\1\s\src\Controls\src\Core\Platform\GestureManager\GesturePlatformManager.Android.cs:line 204
   at Android.Views.View.IOnTouchListenerImplementor.OnTouch(View v, MotionEvent e) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-33/mcw/Android.Views.View.cs:line 4196
   at Android.Views.View.IOnTouchListenerInvoker.n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_(IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-33/mcw/Android.Views.View.cs:line 4137
   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLL_Z(_JniMarshal_PPLL_Z callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, IntPtr p1) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 236

然而,这一例外在Azure存储上不会持续存在.这只发生在App.cs上的HandleUnhandledException方法的异常情况下.

异常被写入到输出窗口而不是Azure表的事实真的让我感到困惑.

你知道为什么会发生这种情况吗,或者我如何使用Serilog获取未处理的异常并将它们存储在Azure表中?我应该对我的代码进行一些更改吗?

我发现了什么

推荐答案

我认为这里有几个 Select :

  • 异常是在它可以冒泡到应用程序域的UnhandledException事件处理程序之前被捕获的.我不熟悉MAIU是如何处理将错误记录到控制台的,但也许这可能是问题所在.
  • 在您的CreateMauiApp方法中,您正在设置应用程序并注册视图模型、视图等,OnSkipOnboardingCommand可能在HandleUnhandledException处理程序连接到应用程序域的UnhandledException事件之前被调用.您可以通过在CreateMauiApp方法的开头连接UnhandledException事件处理程序来测试这一点.
  • 正如你的帖子上的一位 comments 者已经指出的那样,在被操作系统终止之前,你的进程可能没有足够的时间将日志(log)写入Azure表.您可以通过将UnhandledExceptionEventArgs对象的ExitApplication属性更改为false来测试这是否是问题所在,这将允许它保持运行.

我还建议阅读微软关于UnhandledException事件的文档,在记忆中,你将无法捕捉到某些类别的关键异常.

Csharp相关问答推荐

在C#c/await中,延迟长度是否会影响控制返回调用者?

应用程序启动时出现错误:操作无法同时使用表单和SON主体参数

在WPF.NET 6中使用C++/WinRT组件(但实际上是任何WinRT组件)

react 式扩展连接中的非交叉LeftDurationTimeout

向类注入一个工厂来创建一些资源是一个好的实践吗?

将列表字符串映射为逗号分隔字符串<>

如果存在对CodeAnalysis.CSharp的引用,则不能引用netStandard2.0库

如何在C#中使用正则表达式抓取用逗号分隔的两个单词?

自动映射程序在GroupBy之后使用项目

如何测量在使用UTF8而不是C#中的UTF16编码字符串时内存使用量的增长

如何将此方法参数化并使其更灵活?

如何通过属性初始化器强制初始化继承记录内的属性?

Docker Container中的HttpRequest后地址不可用

正在try 从Blazor中的API读取JSON

在两个已具有一对多关系的表之间添加另一个一对多关系

为什么方法的值在SELECT方法中不会更改?

C#按名称从类获取属性值类型<;t>;,我需要反射吗?

在C#.NET项目中启动时,如何等待提升的PowerShell进程退出?

Azure Functions v4中的Serilog控制台主题

Blazor:搜索框在第一次搜索时不搜索