我有一个用于获取一些信息的服务,该方法在链中有一堆异步调用。
public interface IFooService
{
Task<IFoo> GetFooAsync();
}
具体课程,
public class FooService : IFooService
{
public async Task<IFoo> GetFooAsync()
{
// whole bunch of awaits on async calls and return IFoo at last
}
}
我在启动时注册了此服务,
services.AddTransient<IFooService, FooService>();
该服务还注入了其他一些服务。其中之一,
public class BarService : IBarService
{
private readonly IFooService _fooService;
public BarService(IFooService fooService)
{
_fooService = fooService;
}
public async Task<IBar> GetBarAsync()
{
var foo = await _fooService.GetFooAsync();
// additional calls & processing
var bar = SomeOtherMethod(foo);
return bar;
}
}
IFoo
是应用程序不可或缺的,可在多个服务中使用。我的大部分代码都是async
的缘故,这仅仅是因为它IFooService
和它拥有的一种返回IFoo
的方法。
考虑到这个用例,我希望能够将IFoo
注入所有其他服务,而不是使用IFooService
注入它们。
我试了一下
services.AddTransient<IFoo>(provider =>
{
var fooService = provider.GetService<IFooService>();
var foo = fooService.GetFooAsync().GetAwaiter().GetResult();
return foo;
});
但是当我通过异步进行同步时,它向我发出了一个危险信号,我不确定这是否会引起诸如比赛条件之类的问题。这样做会阻止启动。我正在寻找一种干净的方式来处理此问题,如果我们需要这样的建议吗?谢谢您的帮助。
答案 0 :(得分:2)
但是当我通过异步进行同步时,它向我发出了红旗
对于这个危险信号,是由于您调用了GetFoo
中未定义的方法IFooService
而引起的,它与异步或同步方法无关。
尝试定义的方法
services.AddTransient<IFoo>(provider =>
{
var fooService = provider.GetService<IFooService>();
var foo = fooService.GetFooAsync().Result;
return foo;
});
答案 1 :(得分:1)
services.AddTransient<IFoo>(provider =>
{
var fooService = provider.GetService<IFooService>();
var foo = fooService.GetFooAsync().GetAwaiter().GetResult();
return foo;
});
此选项比.Result
稍好一点,因为.Result
会将您所有的异常包装到AggregateException
中,并且我建议的代码不会产生副作用。另外,不要忘记两个选项都不会异步运行,它将同步运行以阻塞线程
答案 2 :(得分:0)
2其他选项
1)注入Func>作为瞬态,呼叫者可以等待。 2)Task.Run(async()等待abc).Wait(); //由于创建任务且问题较少,因此死锁少得多。