Revit Addin中的AppDomain.CurrentDomain.UnhandledException

时间:2016-11-16 08:30:28

标签: c# appdomain unhandled-exception revit-api revit

我想在自己的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();
    }

感谢您的帮助

3 个答案:

答案 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()等。

相关问题