首页 > 解决方案 > Tibco Spotfire WinForm 中未捕获的异常

问题描述

我们在 TIBCO Spotfire 中运行了一个扩展程序,与它有一个非常复杂的交互。这是一个 C# Winform 应用程序。我希望能够捕获所有未捕获的异常,而不是让它们使应用程序崩溃。一个例子发生在我们编写的一个事件处理程序中。当我让 Visual Studio 捕获异常时,我们的事件处理程序下面的调用堆栈是:

    C1.Win.C1Command.4.dll!C1.Win.C1Command.C1Command.OnClick(C1.Win.C1Command.ClickEventArgs e)    Unknown
C1.Win.C1Command.4.dll!C1.Win.C1Command.C1Command.Invoke(C1.Win.C1Command.ClickEventArgs e) Unknown
C1.Win.C1Command.4.dll!C1.Win.C1Command.BarAddIn.InvokeCommandLink(C1.Win.C1Command.C1CommandLink cl, C1.Win.C1Command.BarAddIn.InvokedBy invokedBy)    Unknown
C1.Win.C1Command.4.dll!C1.Win.C1Command.ToolBarAddIn.OnMouseUp(System.Windows.Forms.MouseEventArgs e)   Unknown
C1.Win.C1Command.4.dll!C1.Win.C1Command.C1ToolBar.OnMouseUp(System.Windows.Forms.MouseEventArgs e)  Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks)   Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m)   Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam)  Unknown
[Native to Managed Transition]  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData)  Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context)    Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Unknown
Spotfire.Dxp.Forms.dll!Spotfire.Dxp.Forms.MainFormManager.Run() Unknown
Spotfire.Dxp.Main.dll!Spotfire.Dxp.Main.Program.StartMain.AnonymousMethod__0()  Unknown
Spotfire.Dxp.Framework.dll!Spotfire.Dxp.Framework.ApplicationModel.ApplicationThread.AssociateToCurrentThread(Spotfire.Dxp.Framework.DocumentModel.Executor executor)   Unknown
Spotfire.Dxp.Loader.dll!Spotfire.Dxp.Loader.ProgramLoader.StartMain(Spotfire.Dxp.Framework.ApplicationModel.ConnectivityService connectivityService, string startupFile, System.IDisposable startupFileLock, string qualificationExportPath, string applicationProfilerConfigPath, string startupUri, Spotfire.Dxp.Loader.SplashWrapper splashWrapper, Spotfire.Dxp.Framework.ApplicationModel.ModulesService modulesService, Spotfire.Dxp.Framework.ApplicationModel.LocalizationService localizationService, Spotfire.Dxp.Framework.AddIn.Registry.AddInRegistry addIns, Spotfire.Dxp.Framework.ApplicationModel.CobrandingService cobrandingService, bool disableMultipleViews, string pathToDxpExeWithConfig)   Unknown
Spotfire.Dxp.Loader.dll!Spotfire.Dxp.Loader.ProgramLoader.PrepareForStartingMain(System.Collections.Generic.Dictionary<string, object> state, string[] args, string upgradePath, System.Collections.Generic.List<string> moduleFolders, Spotfire.Dxp.Loader.StarterSplash starterSplash, bool isCalledByLegacyStarter, bool isLog4netConfigured)    Unknown
Spotfire.Dxp.Loader.dll!Spotfire.Dxp.Loader.ProgramLoader.InternalExecute(System.Collections.Generic.Dictionary<string, object> state, string[] args, object splash, System.Version starterVersion, System.Collections.Generic.IList<string> moduleFolderList, string upgradePath, bool isCalledByLegacyStarter)    Unknown
Spotfire.Dxp.Loader.dll!Spotfire.Dxp.Loader.ProgramLoader.Execute(System.Collections.Generic.Dictionary<string, object> state, string[] args, object splash, System.Version starterVersion, System.Collections.Generic.IList<string> moduleFolderList, string upgradePath)  Unknown
[Native to Managed Transition]  
[Managed to Native Transition]  
Spotfire.Dxp.exe!Starter.Program.ProgramLoaderWrapper.Execute(string fullLoaderAssemblyName, System.Collections.Generic.Dictionary<string, object> loaderState, string[] args, object splash, System.Version starterVersion, System.Collections.Generic.IList<string> moduleFolderList, string upgradePath) Unknown
[AppDomain (Spotfire.Dxp.exe, #1) -> AppDomain (Spotfire.ApplicationHost, #2)]  
Spotfire.Dxp.exe!Starter.Program.Run(Spotfire.Dxp.Starter.StarterSplashWrapper splash, System.Collections.Generic.Dictionary<string, object> loaderState, bool serverless)  Unknown
Spotfire.Dxp.exe!Starter.Program.ExecuteRunLoopWithBootstrapFlag(string[] cmdArgs, bool calledByBootstrapper)   Unknown
Spotfire.Dxp.exe!Starter.Program.Main(string[] cmdArgs) Unknown

如您所见,我们不拥有 Main,Spotfire 拥有。

据我所知,最早的入口点是 OnApplicationInstanceCreated。

通常在 Winform 应用程序中,您需要执行以下 2 项:

AppDomain.CurrentDomain.UnhandledException += ...
Application.ThreadException += ...

请参阅https://stackoverflow.com/a/5762806/788301。你还需要打电话

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

但是,一旦在线程上创建了任何控件,就无法更改线程异常模式。这意味着我们设置它为时已晚。没有 GetUnhandledExceptionMode 所以我不知道它是什么,但我怀疑它设置为不捕获它们,否则我希望
Application_ThreadException 捕获我们的异常。据我所知,可能还有其他一些事情会在这两条路径之外引发异常 - 与线程池和/或计时器和/或调度程序有关,但我认为在这种情况下,我们不能 SetUnhandledExceptionMode 是没被抓到的原因。在本地和托管之间有一些切换的事实也可能是一个因素。

    protected override void OnApplicationInstanceCreated(AnalysisApplication application)
    {
        ...
        System.Windows.Forms.Application.ThreadException += Application_ThreadException; // Main thread exceptions. Currently not caught probably because of UnhandledExceptionMode
        try
        {
            // crashes with "Thread exception mode cannot be changed once any Controls are created on the thread."
            System.Windows.Forms.Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // unhandled exceptions on other threads 
        ...
    }

我希望 Spotfire 有类似 UnhandledException 事件,但我没有看到任何事件。当然,我可以对我们编写的每个方法都进行尝试,但此时代码太多以至于不可行。

标签: c#spotfiretibcounhandled-exception

解决方案


推荐阅读