在异步方法中运行同步命令
您好,我有一些异步方法(如web请求),需要在一系列命令之间调用。我需要子命令同步运行,因此无法使用CommandAsync(),因为子命令具有用户交互,我希望等待所有这些都完成(子命令例如可以获得选择集)
Autodesk.AutoCAD.Runtime。例外:eInvalidInput
示例:
public static async void CmdTest()
{
var activeDoc = Application.DocumentManager.MdiActiveDocument;
Editor editor = activeDoc.Editor;
await Task.Delay(100); // this could be e.g. some async web request in practice
try
{
editor.Command("BCOUNT");// some dummy command
editor.WriteMessage("finished CMD_TEST\n");
}
catch (Exception ex)
{
editor.WriteMessage("failed CMD_TEST\n");
}
}
原因是什么,如何解决
为完整起见,以下是一个工作和非工作命令()调用的两个堆栈:
> test_autocad.dll!Tools.AutoCAD.CommandsTest.CmdTestWorking()
accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(System.Reflection.MethodInfo mi, object commandObject, bool bLispFunction)
accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(System.Reflection.MethodInfo mi, object commandObject, bool bLispFunction)
accoremgd.dll!Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
accore.dll!CCmdThroat::arxCallNativeFunction()
accore.dll!Command::doCommand()
accore.dll!runTheCommand()
accore.dll!CommandProcessor::mainCmdLoop()
accore.dll!CCmdThroat::Run()
accore.dll!AcApAppImp::internalRun()
accore.dll!AcApAppImp::run(void)
acad.exe!00007ff764026c41()
mfc140u.dll!00007ff8109a3840()
acad.exe!00007ff764039602()
kernel32.dll!00007ff859ca7034()
ntdll.dll!00007ff85b822651()
> test_autocad.dll!Tools.AutoCAD.CommandsTest.CmdTestFailing()
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0()
mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()
mscorlib.dll!System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.GetActionLogDelegate.AnonymousMethod__0()
acpal.dll!00007fffe380d218()
acpal.dll!00007fffe380d2e4()
accore.dll!AcApAppImp::notifyMessagePreviewObservers(struct tagMSG &,bool)
accore.dll!AcApApp::notifyMessagePreviewObservers(struct tagMSG &)
acad.exe!CAcadApp::PreTranslateMessage()
mfc140u.dll!AfxInternalPumpMessage()
acad.exe!CAcadApp::PumpMessage(void)
acad.exe!CAcadApp::runMessageLoop()
accore.dll!AcApAppImp::runMessageLoop(void)
accore.dll!win_event(void)
accore.dll!CCmdThroat::select_device()
accore.dll!CDig::digin()
accore.dll!CAcCoreInput::GetRawInput()
accore.dll!CAcCoreInput::egetdat()
accore.dll!getCommandNameOrGripSelectionInput()
accore.dll!CCmdThroat::Run()
accore.dll!AcApAppImp::internalRun()
accore.dll!AcApAppImp::run(void)
acad.exe!CAcadApp::Run(void)
mfc140u.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)
acad.exe!__scrt_common_main_seh()
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()
**** Hidden Message ***** 原因是AutoCAD运行在UI线程上,就像石器时代的大多数遗留软件一样
修复可能涉及将命令添加到一个列表中,该列表在异步例程返回且应用程序处于静止状态后在主线程上执行<你可以试试调度器。调用 我在打电话,所以我没有掌握语法。我猜这种方法是不可预测的,不可靠的。我不会相信它。 Application.DocumentManager.IsApplicationContext 似乎很合适。当它返回 true 时,我们不在命令上下文中,并且当我们已经在命令上下文中时,它似乎也总是返回 false。
页:
[1]