使用来自空闲事件处理程序的 Revit API(2014) 关闭 ActiveUIDocument

Close ActiveUIDocument using Revit API(2014) from Idling Event Handler

有什么方法可以使用 Revit 关闭 ActiveUIDocument API?我已经创建了一个单独的插件来关闭从 Revit GUI 运行的 ActiveUIDocument,但是当我尝试从 Idling 事件处理程序调用该插件时,没有任何反应。请帮忙。

下面是我的插件代码:

private void CloseDoc(object obj)
{
     SendKeys.SendWait("^{F4}");
}

public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
     Threadpool.QueueUserWorkItem(new WaitCallback(Close));
     return Result.Succeeded;      
}

用于从空闲事件处理程序中调用插件的代码:

     RevitCommandId id_built_in = RevitCommandId.LookupPostableCommandId(PostableCommand.SheetIssuesOrRevisions);
     RevitCommandId addinID = RevitCommandId.LookupCommandId("1869A8A1-A239-41CF-9A79-96234D92DEF4");
     app.PostCommand(addinID);

Addinn 清单文件:

<?xml version="1.0"?>
<RevitAddIns>
  <AddIn Type="Command">
    <Assembly>AddinExternalLauncher.dll</Assembly>
    <ClientId>1869A8A1-A239-41CF-9A79-96234D92DEF4</ClientId>
    <FullClassName>AddinExternalLauncher.AddinLauncher</FullClassName>
    <Text>Addin External Launcher</Text>
    <Description></Description>
    <VisibilityMode>AlwaysVisible</VisibilityMode>
    <VendorId>ADSK</VendorId>
    <VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
</RevitAddIns>

调用插件后日志输出的最后几行:

' 1:< total bytes expanded: 35414988 
' 1:< ;EES;0;0;86;0;0;0;0;0;14; 
' 1:<  0 ModelServerState "Destroyed": Current server = "Not Queried", Model server = "", Model server state = "Not Applicable" 
' 1:<   System (MB) [Available /  Total ]  [Revit Memory Usage (MB)   ] 
' 1:< RAM Statistics:     3385 /     8040       623=InUse      629=Peak  
' 1:< VM  Statistics:  8384617 /  8388607       536=InUse      542=Peak  
 ' 1:< ::9:: Delta VM: Avail -13 -> 8384597 MB, Used +28 -> 564 MB, Peak +21 -> 564 MB; RAM: Avail -26 -> 3360 MB, Used +41 -> 664 MB, Peak +36 -> 665 MB 
 'E 24-Aug-2016 15:02:28.961;   1:< 
 ' [Jrn.File Input Information] COMMON.FILE_INPUT.FILE_TYPE: .rvt 013144064.000000
' 0:< The Idling event callback used 53 seconds 
' 3:< ::10:: Delta VM: Avail -20 -> 8384577 MB, Used +6 -> 570 MB, Peak +6 -> 570 MB; RAM: Avail -2 -> 3358 MB, Used +3 -> 667 MB, Peak +1 -> 667 MB 
'  0.114085      4:<<From Parking Area: ;PERF;MISC;generating greps 
' 0:< ::10:: Delta VM: Avail +5 -> 8384583 MB, Used -13 -> 558 MB; RAM: Avail +2 -> 3361 MB, Used -7 -> 661 MB, Peak +0 -> 668 MB 
'  0.372841   1:<<;PERF;MISC;drawing/ALL_GAPS   0.258756/TurnOff_GAPs 74% 
'C 24-Aug-2016 15:02:29.386;   0:< idle0_doc 
'H 24-Aug-2016 15:02:29.386;   0:< 
Jrn.Directive "AllowPressAndDrag"  _
        , 1
' 0:< <<Begin build CT>>
'
'Edit mode: IDR_COMMON
'Command: ID_BUTTON_SELECT
'Category: 0
'Bar list: 
'   Dialog_Revit_DynamicLabelDBar
'   Dialog_Essentials_FilterSelectionNew
'Presenter list: 
'   PP_DebugTab_Binding_Demo
'Product: Architecture
'
'
'***********************************************************
'***********************************************************
'<<End build CT>> 

为什么不直接从 Idling 处理程序调用您的方法?

private void ApplicationOnIdling(object sender, IdlingEventArgs idlingEventArgs)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(Close));
}

既然如此,为什么不使用 Task 而不是 ThreadPool?

Task.Run(() => SendKeys.SendWait("^{F4}"));

它完成了同样的事情,而且比使用带有未使用参数的额外方法更干净。

当然,当您从 Idling 事件处理程序调用外部命令时,什么也不会发生。

空闲事件处理程序在 Revit 无事可做时执行。

如果必须执行您的命令,Revit 有事情要做,因此空闲事件处理程序无法工作。

以编程方式触发外部命令执行的正确且唯一的方法是通过 PostCommand 功能:

http://thebuildingcoder.typepad.com/blog/2013/10/programmatic-custom-add-in-external-command-launch.html

我喜欢 cs1088 上面的回答,希望能为您解决问题。