在启动时在AddTransient中调用异步方法-Asp.Net Core

时间:2019-01-24 04:57:18

标签: c# asp.net-core async-await startup

我有一个用于获取一些信息的服务,该方法在链中有一堆异步调用。

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;
});

但是当我通过异步进行同步时,它向我发出了一个危险信号,我不确定这是否会引起诸如比赛条件之类的问题。这样做会阻止启动。我正在寻找一种干净的方式来处理此问题,如果我们需要这样的建议吗?谢谢您的帮助。

3 个答案:

答案 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(); //由于创建任务且问题较少,因此死锁少得多。