我们有一个 WPF 和/或 Winforms 客户端正在使用的库。
我们提供了一个类似于以下的异步方法:
Task<int> GetIntAsync()
我们还(不幸地)提供了一个同步包装方法:
int GetInt();
它本质上只是调用异步方法并调用.Result
其任务。
我们最近意识到在某些情况下,一些代码GetIntAsync
需要在主 UI 线程上运行(它需要使用标记为“单”线程模型的遗留 COM 组件(即组件必须在主 STA 线程中运行,而不仅仅是任何STA线程)
所以问题是当GetInt()
在主线程上调用时,它会死锁,因为
- 阻塞主
.Result
线程, - 其中的代码
GetIntAsync()
用于Dispatcher.Invoke
尝试在主线程上运行。
同步方法已被使用,因此删除它将是一项重大更改。因此,我们选择在我们的同步方法中使用WaitWithPumpingGetInt()
来允许对主线程的调用工作。
GetInt()
除了从他们的 UI 代码中使用的客户端外,这工作正常。以前,他们预计 usingGetInt()
会使他们的 UI 无响应——也就是说,如果他们GetInt()
从按钮的 click 事件处理程序中调用,他们预计在处理程序返回之前不会处理任何 Windows 消息。现在消息被抽出,他们的 UI是响应式的,并且可以再次单击相同的按钮(并且他们可能没有将他们的处理程序编码为可重入)。
如果有一个合理的解决方案,我们不希望我们的客户在调用GetInt
问题:
- 有没有办法
WaitWithPumping
可以抽出“调用到主”消息,但不抽出其他与 UI 相关的消息? - 如果客户端 UI 表现得好像当前显示了一个模态对话框,尽管它是隐藏的(即用户无法访问其他窗口),这对我们的目的来说就足够了。但是,根据我的阅读,您无法隐藏模式对话框。
- 您能想到的其他解决方法将不胜感激。