Un-subscribing from event in other events

0

I'm failing to un-subscribe to an event while using a BackgroundWorker to handle when the un-subscribe event should be fired. I can un-subscribe in the AsyncRunner but not in BackgroundWorker1_RunWorkerCompleted.

Context: This is part of a plug-in for Autodesk Revit. We want to update some files in the background but while we are doing so we want to catch the command to the affected parts and cancel it.

I can successfully catch the command and cancel it, but I cant get it un-subscribed once the BackgroundWorker ends.

No exceptions are thrown at any point. Edit: It throws a "System.AccessViolationException HResult=0x80004003 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=Cannot evaluate the exception source StackTrace: Cannot evaluate the exception stack trace" when the host program exits.

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;
        }

    }
}

I'm pretty new to EventHandlers but expected that I could un-subscribe from Command.BeforeExecuted within BackgroundWorker1_RunWorkerCompleted but it stays subscribed.

c#
.net
events
event-handling
revit-api
asked on Stack Overflow Apr 2, 2019 by Motto • edited Apr 2, 2019 by Motto

1 Answer

0

It looks and sounds to me as if you are trying to interact without being inside a valid Revit API context. That is not allowed and would throw such an exception, if you are lucky. If worst comes to worst, you might not see any exception at all and just corrupt your model. Catastrophe!

answered on Stack Overflow Apr 3, 2019 by Jeremy Tammik

User contributions licensed under CC BY-SA 3.0