乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 77|回复: 2

在异步方法中运行同步命令

[复制链接]
stw

1

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
6
发表于 2022-3-24 10:39:42 | 显示全部楼层 |阅读模式
您好,
我有一些异步方法(如web请求),需要在一系列命令之间调用。我需要子命令同步运行,因此无法使用CommandAsync(),因为子命令具有用户交互,我希望等待所有这些都完成(子命令例如可以获得选择集)
Autodesk.AutoCAD.Runtime。例外:eInvalidInput
示例:
  1.     [CommandMethod("CMD_TEST")]
  2.     public static async void CmdTest()
  3.     {
  4.         var activeDoc = Application.DocumentManager.MdiActiveDocument;
  5.         Editor editor = activeDoc.Editor;
  6.         await Task.Delay(100);   // this could be e.g. some async web request in practice
  7.         try
  8.         {
  9.             editor.Command("BCOUNT");  // some dummy command
  10.             editor.WriteMessage("finished CMD_TEST\n");
  11.         }
  12.         catch (Exception ex)
  13.         {
  14.             editor.WriteMessage("failed CMD_TEST\n");
  15.         }
  16.     }

原因是什么,如何解决
为完整起见,以下是一个工作和非工作命令()调用的两个堆栈:
  1. >        test_autocad.dll!Tools.AutoCAD.CommandsTest.CmdTestWorking()
  2.         accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(System.Reflection.MethodInfo mi, object commandObject, bool bLispFunction)
  3.         accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(System.Reflection.MethodInfo mi, object commandObject, bool bLispFunction)
  4.         accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
  5.         [Native to Managed Transition]       
  6.         accore.dll!CCmdThroat::arxCallNativeFunction()
  7.         accore.dll!Command::doCommand()
  8.         accore.dll!runTheCommand()
  9.         accore.dll!CommandProcessor::mainCmdLoop()
  10.         accore.dll!CCmdThroat::Run()
  11.         accore.dll!AcApAppImp::internalRun()
  12.         accore.dll!AcApAppImp::run(void)
  13.         acad.exe!00007ff764026c41()
  14.         mfc140u.dll!00007ff8109a3840()
  15.         acad.exe!00007ff764039602()
  16.         kernel32.dll!00007ff859ca7034()
  17.         ntdll.dll!00007ff85b822651()
  18. >        test_autocad.dll!Tools.AutoCAD.CommandsTest.CmdTestFailing()
  19.         [Resuming Async Method]       
  20.         mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
  21.         mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
  22.         mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
  23.         mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0()
  24.         mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()
  25.         mscorlib.dll!System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.GetActionLogDelegate.AnonymousMethod__0()
  26.         acpal.dll!00007fffe380d218()
  27.         acpal.dll!00007fffe380d2e4()
  28.         accore.dll!AcApAppImp::notifyMessagePreviewObservers(struct tagMSG &,bool)
  29.         accore.dll!AcApApp::notifyMessagePreviewObservers(struct tagMSG &)
  30.         acad.exe!CAcadApp::PreTranslateMessage()
  31.         mfc140u.dll!AfxInternalPumpMessage()
  32.         acad.exe!CAcadApp::PumpMessage(void)
  33.         acad.exe!CAcadApp::runMessageLoop()
  34.         accore.dll!AcApAppImp::runMessageLoop(void)
  35.         accore.dll!win_event(void)
  36.         accore.dll!CCmdThroat::select_device()
  37.         accore.dll!CDig::digin()
  38.         accore.dll!CAcCoreInput::GetRawInput()
  39.         accore.dll!CAcCoreInput::egetdat()
  40.         accore.dll!getCommandNameOrGripSelectionInput()
  41.         accore.dll!CCmdThroat::Run()
  42.         accore.dll!AcApAppImp::internalRun()
  43.         accore.dll!AcApAppImp::run(void)
  44.         acad.exe!CAcadApp::Run(void)
  45.         mfc140u.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)
  46.         acad.exe!__scrt_common_main_seh()
  47.         kernel32.dll!BaseThreadInitThunk()
  48.         ntdll.dll!RtlUserThreadStart()

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

23

主题

239

帖子

6

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
327
发表于 2022-3-25 03:45:46 | 显示全部楼层
原因是AutoCAD运行在UI线程上,就像石器时代的大多数遗留软件一样
修复可能涉及将命令添加到一个列表中,该列表在异步例程返回且应用程序处于静止状态后在主线程上执行<你可以试试调度器。调用…我在打电话,所以我没有掌握语法。我猜这种方法是不可预测的,不可靠的。我不会相信它。
回复

使用道具 举报

stw

1

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
6
发表于 2022-3-25 12:41:14 | 显示全部楼层
Application.DocumentManager.IsApplicationContext 似乎很合适。当它返回 true 时,我们不在命令上下文中,并且当我们已经在命令上下文中时,它似乎也总是返回 false。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 01:31 , Processed in 0.189014 second(s), 69 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表