作为一个例子,假设我们有这个:
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
。作为副作用,您必须仅在MyClass.MySynchronousNonBlockingFunction()
空格内调用async
才能按预期工作。
我认为这对来电者来说不太好。因为应用程序开发团队中的懒惰开发人员可能会在没有MySynchronousNonBlockingFunction()
的情况下调用await
,然后应用程序将无法正常运行。我想在内部处理我的代码中的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#中找到的所有方法都阻止了正在运行的线程。
但是,我如何实现手动等待?还有另一种方法可以达到这个目的吗?
答案 0 :(得分:1)
实际上,我希望暂停ui线程继续在某个位置执行,然后再次恢复它以便稍后继续执行(从CallStack快照位置)。但我不想冻结或实际上暂停therad因此它必须可以自由地再次处理其他调用堆栈中的其他工作。我想要的女巫实际上与任务执行的await关键字的工作相同。还有其他选择可以使用吗?
但await
的工作原理并非如此。 await
通过返回,然后稍后继续该方法来工作。特别是,调用堆栈未捕获。
如果您想要切换线程堆栈,请查看fibers。但是,光纤API没有.NET绑定,如果你尝试使用光纤而不是线程,很可能会破坏很多.NET代码。然后是光纤是否实际上可以成为UI元素的STA上下文的整个问题;我真的不确定那一个。简而言之,这里是龙。
你的解决方案是什么?
嗯,模式对话框 - by definition - 假设阻止其他对话框并运行嵌套的消息循环。
如果您不想要此行为,请改为编写无模式对话框。即,致电Show
而不是ShowDialog
。
答案 1 :(得分:0)
GUI窗口处理程序是消息驱动的状态机。您必须编写反映该代码的代码。这意味着不,你不能只是等待,你不应该尝试。