首页 > 解决方案 > 取消订阅其他活动中的活动

问题描述

在使用 BackgroundWorker 处理何时应触发取消订阅事件时,我未能取消订阅事件。我可以在 AsyncRunner 中取消订阅,但不能在 BackgroundWorker1_RunWorkerCompleted 中取消订阅。

上下文:这是 Autodesk Revit 插件的一部分。我们想在后台更新一些文件,但是当我们这样做时,我们希望将命令捕获到受影响的部分并取消它。

我可以成功捕获命令并取消它,但是一旦 BackgroundWorker 结束,我就无法取消订阅它。

任何时候都不会抛出异常。 编辑:它抛出“System.AccessViolationException HResult=0x80004003 消息=尝试读取或写入受保护的内存。这通常表明其他内存已损坏。源=无法评估异常源 StackTrace:无法评估异常堆栈跟踪”时主机程序退出。

using System.Threading;
using System.ComponentModel;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;

namespace RevitAsyncTest
{
    class Asyncer 
    {
        private static AddInCommandBinding Command { get; set; }

        internal static void AsyncRunner(UIControlledApplication app)
        {
            // Assign command and eventhand and subscribe to commandevents. 
            Command = app.CreateAddInCommandBinding(RevitCommandId.LookupCommandId("ID_VISUAL_PROGRAMMING_DYNAMO"));
            Command.BeforeExecuted += DynaExecuted;

            // Setup background worker 
            BackgroundWorker BackgroundWorker1 = new BackgroundWorker();
            BackgroundWorker1.DoWork += BackgroundWorker1_DoWork;
            BackgroundWorker1.RunWorkerCompleted += 
            BackgroundWorker1_RunWorkerCompleted;
            BackgroundWorker1.RunWorkerAsync();

            // I can un-subscribe here but this defeats the purpose
            Command.BeforeExecuted -= DynaExecuted;
        }

        private static void DynaExecuted(object sender, BeforeExecutedEventArgs e)
        {
            // Make user facing explanation
            e.Cancel = true;
        }

        private static void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Boilerplate code - replace later. 
            Thread.Sleep(30000);
        }

        private static void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {   
            // I can't un-subscribe here?!?!
            Command.BeforeExecuted -= DynaExecuted;
        }

    }
}

我对 EventHandlers 很陌生,但希望我可以在 BackgroundWorker1_RunWorkerCompleted 中取消订阅 Command.BeforeExecuted 但它保持订阅状态。

标签: c#.neteventsevent-handlingrevit-api

解决方案


在我看来,它看起来和听起来好像您正在尝试在没有处于有效 Revit API 上下文中的情况下进行交互。如果幸运的话,这是不允许的,并且会抛出这样的异常。如果最坏的情况发生,您可能根本看不到任何异常,只会破坏您的模型。灾难!


推荐阅读