我有一个带有一些异步方法的类,这些方法采用处理程序类来决定在成功或失败时要做什么。
public class FooModel
{
private FooState fooState;
public async Task UpdateFooAsync(IHandler handler)
{
try
{
var newFooState = await Something();
fooState = newFooState;
handler.Success();
}
catch
{
handler.Error();
}
}
}
public interface IHandler
{
void Success();
void Error();
}
我可能会从代码中的几个不同位置调用 UpdateFooAsync。根据我从哪里调用它,我可能想做不同的事情。比如一个同步的例子:
public async void update_click(object sender, RoutedEventArgs e)
{
await UpdateFooAsync(new Handler1());
}
public class Handler1 : IHandler
{
public void Success()
{
Provider.Page.text = "hello";
}
public void Error() {}
}
但我可能还想在之后执行异步操作:
private async void updateAndThenSomething_click(object sender, RoutedEventArgs e)
{
await UpdateFooAsync(new Handler2());
}
// this will generate not implemented error obviously
public class Handler2 : IHandler
{
public async void SuccessAsync()
{
await Provider.OperationAsync();
}
public void Error() {}
}
但是 FooModel 不知道我接下来是要进行同步操作还是异步操作。它不应该知道。有没有办法让 handler.Success() 运行同步代码或异步代码?我读了一些 Stephen Toub 的文章 ( link ),这似乎暗示我不应该让成功成为一项任务,然后在 UpdateFooAsync try block 中等待该任务。
我想另一种选择是完全放弃处理程序接口(interface)。但这需要大量的重构。上面的情况在我的代码中经常发生,往往不止是成功和错误。我想强制使用我的代码的人指定在成功、错误或其他情况下会发生什么。这就是我使用该界面的原因。我想我也可以通过抛出不同类型的异常来做到这一点,但我也不确定这是否是个好主意。
最佳答案
您可以声明您的处理程序接口(interface)以返回一个 Task
,然后在同步情况下只需使用 Task.FromResult
返回。例如
public interface IHandler
{
Task Success();
void Error();
}
public class Handler1 : IHandler
{
public Task Success()
{
Provider.Page.text = "hello";
return Task.FromResult<object>(null);
}
public void Error() {}
}
public class Handler2 : IHandler
{
public async Task Success()
{
return Provider.OperationAsync();
}
public void Error() {}
}
关于c# - 如何运行可能同步或可能异步的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27721286/