我想在自己的Revit addin
中使用崩溃记者,但AppDomain.CurrentDomain.UnhandledException
永远不会被调用。似乎Revit本身管理未处理的预期并显示其自己的崩溃对话框。在Revit捕获它们之前,我应该怎么做才能捕获revit addin中所有未处理的异常?
我已经尝试了以下几行代码,但它不起作用:它永远不会进入处理程序方法:
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
throw new NotImplementedException();
}
感谢您的帮助
答案 0 :(得分:1)
我认为在 Revit 主线程中没有办法做到这一点。
但是,如果您将在单独的线程中运行您的插件,Revit 将不会处理该线程中的异常,并且会触发 UnhandledExceptions 事件(很可能 Revit 也会崩溃)。
如果您的插件在 wpf 上,您可以像这样在单独的线程中启动它,甚至可以处理来自该线程的异常。
namespace ClassLibrary2
{
[Transaction(TransactionMode.Manual)]
public class Startup : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
App.ThisApp.ShowFormSeparateThread();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
return Result.Succeeded;
}
}
}
_
public void ShowFormSeparateThread()
{
if ( !(_uiThread is null) && _uiThread.IsAlive )
return;
_uiThread = new Thread(() =>
{
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
Dispatcher.CurrentDispatcher.UnhandledException += (sender, args) =>
{
MessageBox.Show("Err" + args.Exception.Message);
args.Handled = true;
};
_mMyForm = new MainWindow();
_mMyForm.DataContext = new MainViewModel();
_mMyForm.Closed += (s, e) => Dispatcher.CurrentDispatcher.InvokeShutdown();
_mMyForm.Show();
Dispatcher.Run();
});
_uiThread.SetApartmentState(ApartmentState.STA);
_uiThread.IsBackground = true;
_uiThread.Start();
}
如果您想获取有关 Revit 中所有异常的信息,即使是其他插件抛出的异常,只需使用
AppDomain.CurrentDomain.FirstChanceException += (sender, args) =>
{
//your code here
};
答案 1 :(得分:0)
您是否有任何特殊原因想要在try-catch块中处理此逻辑而不是订阅事件?
在这种情况下,顺便说一句,我相信你正在订阅应用程序窗口的事件处理程序--Revit永远不会让它在链条上走得那么远,这就是为什么它没有进入你创建的处理程序方法。< / p>
答案 2 :(得分:0)
您是否要创建一个通用的崩溃报告程序,以捕获与外接程序无关的异常?我认为Revit加载项是不可能的。如果您要这样做,我将研究为特定的“错误”关键字解析活动日志文件。这将提供有关Revit内部故障的更多信息。
如果您要为自己的加载项创建崩溃报告器,那么我只需要确保将Revit调用的方法中的代码包含在Try / Catch块中,即可记录/报告抛出的所有异常。
[Transaction(TransactionMode.ReadOnly)]
public class MyCommand: IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
try
{
//do stuff
} catch (Exception exp) {
CrashReporter.LogException(exp);
throw;
}
}
然后将其应用于外接程序中的任何其他入口点,例如IExternalApplication.StartUp()
,IExternalApplication.ShutDown()
等。