如何手动实现等待
本文关键字:等待 实现 何手动 | 更新日期: 2023-09-27 18:35:45
作为一个例子,假设我们有这个:
public class MyClass
{
public async Task<bool?> MySynchronousNonBlockingFunction()
{
await here ...
return MyDialogResult;
}
}
调用方必须调用我的函数,如下所示:
public async void Button_Click()
{
var instance = new MyClass();
var result = await instance.MySynchronousNonBlockingFunction();
if (result == true)
{
some work ...
}
}
但是使用Task
来等待,迫使你使你的MySynchronousNonBlockingFunction()
功能async
。作为副作用,您必须仅在async
空内调用MyClass.MySynchronousNonBlockingFunction()
才能按预期工作。
我认为这对呼叫者来说并不好。因为应用程序开发团队中的懒惰开发人员可能会在没有await
的情况下调用MySynchronousNonBlockingFunction()
,然后应用程序将无法正常工作。我想在我的代码内部处理这个async
操作,而不是调用方。为了防止这种开发错误。和这个一样:
public void Button_Click()
{
var instance = new MyClass();
var result = instance.MySynchronousNonBlockingFunction();
if (result == true)
{
some work ...
}
}
事实上,我不想通过等待来冻结正在运行的线程,也不想真正暂停线程,所以它必须可以自由地再次在另一个调用堆栈中处理它的其他工作。我想要的女巫实际上与await
关键字的工作相同,用于Task
执行。有没有其他选择来使用它?您在这里实现await
行为的解决方案是什么?
我知道在 c# 中有一些方法可以lock
对象完全幻想并强制执行堆栈等待。(例如,通过使用Monitor
或Mutex
等)。我在 c# 中找到的所有方式都在阻止正在运行的线程。
但是,如何手动实现等待?有没有其他方法可以达到这个目的?
实际上,我想暂停 ui 线程继续在某个位置执行,然后再次恢复它以稍后继续执行(从 CallStack 快照位置)。但我不想冻结或实际上暂停therad,所以它必须可以再次在另一个调用堆栈中自由处理其他作品。我想要的女巫实际上与任务执行的 await 关键字的工作相同。有没有其他选择来使用它?
不过,这不是await
的工作方式。 await
的工作原理是返回,然后稍后仅恢复该方法。特别是,不会捕获调用堆栈。
如果您想弄乱交换线程堆栈,请查看光纤。但是,纤程 API 没有 .NET 绑定,如果您尝试使用纤程而不是线程,则很可能许多 .NET 代码会中断。然后是整个问题,即光纤是否真的可以成为 UI 元素的 STA 上下文;我真的不确定那个。简而言之,这里是龙。
您的解决方案是什么?
好吧,根据定义,模式对话框应该阻止其他对话框并运行嵌套消息循环。
如果不希望此行为,请改为编写无模式对话框。 即,调用Show
而不是ShowDialog
。
GUI 窗口处理程序是消息驱动的状态机。您必须编写反映这一点的代码。 这意味着不,你不能理智地等待,你不应该尝试。