You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cancel a pending RaiseAsync of an async external event #132
A caller cancels a pending RaiseAsync, and Revit never runs the cancelled work.
The async external events take no CancellationToken.
A caller that stops waiting can't withdraw its work: Revit runs it later, and a change the user cancelled still changes the model.
RaiseAsync of IAsyncExternalEvent, IAsyncExternalEvent<T>, IAsyncRequestExternalEvent<TResult>, and IAsyncRequestExternalEvent<T, TResult> accepts a CancellationToken.
A token cancelled before the call raises nothing, and the task is cancelled at once.
A token cancelled before Revit runs the raise skips the handler for that raise, and the task is cancelled with that token.
A token cancelled while the handler runs changes nothing: the handler runs to its end, and the task completes with its result.
The other raises of the same event run as if the cancelled raise didn't exist.
A raise with ExternalEventOptions.AllowDirectInvocation in API mode checks the token once, before the handler runs.
The async event properties of the [ExternalEvent] generator and its extension methods for several arguments accept the token.
Scenario when this would be used?
A modeless window waits for an edit with a timeout while a modal dialog blocks Revit, and the edit stops once the timeout passes.
A service that stops at Revit shutdown cancels the work it raised.
A remote client cancels its request, and the add-in withdraws the Revit work of that request.
RaiseAsync of the four interfaces, the event classes, and the generated extension methods takes CancellationToken cancellationToken = default. Add-ins compiled against 2027.0 are rebuilt, and custom implementations of the interfaces add the parameter.
A handler can declare a CancellationToken as its last parameter, the way it declares UIApplication first. The asynchronous event passes it the token of RaiseAsync, and the synchronous event passes CancellationToken.None.
A running handler is never interrupted. A handler that receives the token can throw an OperationCanceledException for it, and the task is then canceled.
The handler sees a cancellation requested from another thread, such as a timeout or a remote client. A cancel button on the Revit thread takes effect only after the handler returns.
The first line of the decision above no longer applies: the token is an overload, not an optional parameter.
RaiseAsync() stays, and RaiseAsync(CancellationToken) is declared next to it in the four interfaces, the event classes, and the generated extension methods.
Add-ins compiled against 2027.0 run unchanged. Custom implementations of the interfaces implement the overload.
Activity
Nice3point commentedon Oct 23, 2026
Decision
RaiseAsyncof the four interfaces, the event classes, and the generated extension methods takesCancellationToken cancellationToken = default. Add-ins compiled against 2027.0 are rebuilt, and custom implementations of the interfaces add the parameter.CancellationTokenas its last parameter, the way it declaresUIApplicationfirst. The asynchronous event passes it the token ofRaiseAsync, and the synchronous event passesCancellationToken.None.OperationCanceledExceptionfor it, and the task is then canceled.Nice3point commentedon Oct 23, 2026
Correction
The first line of the decision above no longer applies: the token is an overload, not an optional parameter.
RaiseAsync()stays, andRaiseAsync(CancellationToken)is declared next to it in the four interfaces, the event classes, and the generated extension methods.