我正面临着设计执行网络I/O(对于可重用库)的方法的问题.我读过这个问题
以及更接近我的问题的其他人.
所以,问题是,如果我想提供异步和非异步方法我将如何设计这些?
例如,为了公开方法的非异步版本,我需要做类似的事情
public void DoSomething() {
DoSomethingAsync(CancellationToken.None).Wait();
}
Run Code Online (Sandbox Code Playgroud)
我觉得这不是一个很棒的设计.我想建议(例如)如何定义可以包含在公共方法中的私有方法以提供两个版本.
我读到它的任何地方都说下面的代码应该可行,但事实并非如此.
public async Task DoSomething(int x)
{
try
{
// Asynchronous implementation.
await Task.Run(() => {
throw new Exception();
x++;
});
}
catch (Exception ex)
{
// Handle exceptions ?
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,我没有抓到任何东西,并且在"投掷"线上得到一个"未处理的例外".我在这里很无能为力.
我们有一个由WPF和/或Winforms客户端使用的库.
我们提供了一个类似于的异步方法:
Task<int> GetIntAsync()
Run Code Online (Sandbox Code Playgroud)
我们(不幸的是)还提供了一个同步包装器方法:
int GetInt();
Run Code Online (Sandbox Code Playgroud)
它本质上只是调用异步方法并调用.Result其任务.
我们最近在某些情况下意识到GetIntAsync需要在主UI线程上运行一些代码(它需要使用标记为"单个"线程模型的传统COM组件(即组件必须在主STA线程中运行而不是任何STA线程)
所以问题是,当GetInt()被称为主线程,它会死锁,因为
.Result块为主线,GetIntAsync()使用Dispatcher.Invoke尝试在主线程上运行.同步方法已被消耗,因此删除它将是一个重大变化.因此,我们选择在同步方法中使用WaitWithPumpingGetInt()来允许调用主线程.
除了使用GetInt()UI代码的客户端之外,这种方法很好.以前,他们预计使用GetInt()会使他们的UI无法响应 - 也就是说,如果他们GetInt()从按钮的click事件处理程序中调用,他们会期望在处理程序返回之前不会处理任何Windows消息.现在,消息被泵送,其UI 是响应和相同的按钮可以再次点击(他们可能没有编写自己的处理程序是重入).
如果有一个合理的解决方案,我们希望我们的客户不需要在调用期间针对响应的UI进行编码 GetInt
题:
WaitWithPumping将"调用主要"消息,但不泵送其他UI相关的消息?