Hi,
I have some async methods (like web requests) that need to be called in-between a sequence of commands. I need the sub-commands to run synchronously, so cannot use CommandAsync(), because the sub-commands have user-interaction and I want to wait till all of that is finished (a sub-command e.g. could get a selection set).
However, whenever I try to use editor.Command() in an asynchronous part of an async function I get the following Exception:
Autodesk.AutoCAD.Runtime.Exception: eInvalidInput
Example:
[CommandMethod("CMD_TEST")]
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");
}
}
What is the reason for that and how could it be solved?
For completeness, these are the two stacks of a working and non-working Command() call:
> 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()
[Native to Managed Transition]
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()
[Resuming Async Method]
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()