c# - 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 事件,但我没有看到任何事件。当然,我可以对我们编写的每个方法都进行尝试,但此时代码太多以至于不可行。
解决方案
推荐阅读
- sql - 带有 CTE 的 BigQuery UPDATE 语句
- c# - 敌人没有向玩家射击。仅检测玩家何时在左侧。敌人需要向玩家射击
- magento2 - Magento 2 为不同的客户显示不同的价格导致 Fastly 出现问题
- xamarin - Xamarin.forms plugin.FingerPrint 无法添加到我的项目中
- javascript - JS跳过名称中两部分代码之间的差异
- python - 用 Python 编写的带有 SPIKE 的模糊测试服务器
- ip - iceccd 输出:错误:地址已在使用中
- python - 如何从 div 类下获取 a href 链接?
- openid-connect - 没有为 OIDC 安全方案填充 swagger-ui 上的可用授权模式
- javascript - 滚动到顶部到原始滚动状态