У меня есть асинхронный метод, который возвращает введенное пользователем значение формы ввода. Пока пользователь не отправил ввод, асинхронный метод Task<String> Read()
должен ждать. Когда пользователь отправляет форму ввода, запускается метод Task Execute(EditContext context)
. Поэтому я использовал TaskCompletionSource
, чтобы заблокировать метод Read
, пока форма не была отправлена (что работает для приложения wpf, я сделал).
public async Task<String> Read()
{
StringReadTaskCompletionSource = new TaskCompletionSource<string>();
return await StringReadTaskCompletionSource.Task;
}
protected Task Execute(EditContext context)
{
//...
StringReadTaskCompletionSource
.SetResult((context?.Model as ConsoleInput as ConsoleInput).Text);
}
Но с приведенным выше кодом я получаю:
cris: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer [100] Компонент рендеринга необработанного исключения: не может ждать мониторов в этой среде выполнения. System.Threading.SynchronizationLockException: не может ждать мониторов в этой среде выполнения. at (оболочка, управляемая-родной) System.Threading.Monitor.Monitor_wait (object, int) в System.Threading.Monitor.ObjWait (System.Boolean exitContext, System.Int32 millisecondsTimeout, System.Object obj) ‹0x2e64fc8 + 0x00046› in: 0 в System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout, System.Boolean exitContext) ‹0x2e64ce8 + 0x00022› в: 0 в System.Threading.Monitor.Wait (System.Object obj, System .Int32 миллисекундыTimeout)
Похоже, это результат ограничений razor-wasm в отношении задач и потоков. Я попробовал обходные пути отсюда: https://github.com/dotnet/aspnetcore/issues/14253#issuecomment-534118256
с помощью Task.Yield, но безуспешно. Есть идеи, как обойти эту проблему?
[Edit:] Я думаю, что главный вывод для меня заключается в том, что с помощью razor-wasm (из-за ограничения одного потока) невозможно запустить синхронный метод (Console.ReadLine()
) и ждать ввода пользователя без блокировки всего приложения . Похоже, для этого нет никакого обходного пути. Единственный способ - заменить все эти синхронные вызовы новым асинхронным вызовом, например Console.ReadLineAsync()
.
Read
? - person Evk   schedule 10.11.2020