如何手动实现等待

本文关键字:等待 实现 何手动 | 更新日期: 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对象完全幻想并强制执行堆栈等待。(例如,通过使用MonitorMutex等)。我在 c# 中找到的所有方式都在阻止正在运行的线程。

但是,如何手动实现等待?有没有其他方法可以达到这个目的?

如何手动实现等待

实际上,我想暂停 ui 线程继续在某个位置执行,然后再次恢复它以稍后继续执行(从 CallStack 快照位置)。但我不想冻结或实际上暂停therad,所以它必须可以再次在另一个调用堆栈中自由处理其他作品。我想要的女巫实际上与任务执行的 await 关键字的工作相同。有没有其他选择来使用它?

不过,这不是await的工作方式。 await的工作原理是返回,然后稍后仅恢复该方法。特别是,不会捕获调用堆栈。

如果您想弄乱交换线程堆栈,请查看光纤。但是,纤程 API 没有 .NET 绑定,如果您尝试使用纤程而不是线程,则很可能许多 .NET 代码会中断。然后是整个问题,即光纤是否真的可以成为 UI 元素的 STA 上下文;我真的不确定那个。简而言之,这里是龙。

您的解决方案是什么?

好吧,根据定义,模式对话框应该阻止其他对话框并运行嵌套消息循环。

如果不希望此行为,请改为编写无模式对话框。 即,调用Show而不是ShowDialog

GUI 窗口处理程序是消息驱动的状态机。您必须编写反映这一点的代码。 这意味着不,你不能理智地等待,你不应该尝试。