【发布时间】:2021-02-22 14:02:47
【问题描述】:
我有一个异步方法,它返回输入表单的输入用户值。只要用户没有提交输入,异步方法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);
}
但是通过上面的代码我得到:
暴击:Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:无法等待此运行时的监视器。 System.Threading.SynchronizationLockException:无法等待此运行时的监视器。 在(包装器托管到本机) System.Threading.Monitor.Monitor_wait(object,int) 在 System.Threading.Monitor.ObjWait (System.Boolean exitContext, System.Int32 毫秒超时, System.Object obj) in :0 在 System.Threading.Monitor.Wait(System.Object obj,System.Int32 毫秒超时,System.Boolean exitContext) 在:0 在 System.Threading.Monitor.Wait (System.Object obj, System.Int32 毫秒超时)
这似乎是 razor-wasm 对任务和线程的限制的结果。我从这里尝试了解决方法:https://github.com/dotnet/aspnetcore/issues/14253#issuecomment-534118256
通过使用 Task.Yield 但不成功。知道如何解决这个问题吗?
[编辑:] 我认为对我来说主要结论是,使用 razor-wasm(由于一个线程限制)运行同步方法(Console.ReadLine())并等待用户输入是不可能的,不阻塞整个应用程序。看起来没有解决方法。唯一的方法是用新的异步调用(如Console.ReadLineAsync())替换所有这些同步调用。
【问题讨论】:
-
每次我看到这个都是在打电话的地方。
-
你不能只使用事件,而是在执行中触发它并订阅它而不是
Read? -
ReadLine 方法被调用,假设由第三方调用,我需要提供用户输入。我可以在用户输入内容时创建一个事件,或者当 ReadLine 被触发但我仍然需要等待用户输入。
-
这不是一个兼容 wasm 的解决方案。我也会在 WPF 中对它皱眉。你在一个事件驱动的 UI 中,使用事件。
-
好吧,调用 read 的人应该订阅提到的事件(而在这种情况下 read 被完全删除)。
标签: c# multithreading async-await blazor blazor-webassembly