使用异步调用AddSingleton?

时间:2017-03-11 00:36:33

标签: c# asynchronous asp.net-core singleton .net-core

我添加了这样的单身。

在Startup.cs中我添加以下内容:

services.AddSingleton<MySingleton>();

我想像这样建立我的单身人士(这是不可能的):

public class MySingleton
{

    public MySingleton()
    {
        await InitAsync();
    }

    private async Task InitAsync()
    {
        await Stuff();
    }

}

有没有人知道如何在不造成死锁的情况下解决这个问题?

4 个答案:

答案 0 :(得分:1)

据我所知,ASP.NET Core中的配置不是异步的,因此无法使用异步工厂或类似的东西添加服务。

正因为如此,并且考虑到阻止不是一个大问题,如果它只在应用程序启动时执行一次,我认为你应该在创建服务时阻止。由于ASP.NET Core没有同步上下文,因此也不会导致死锁。

答案 1 :(得分:0)

你能使用它正常构建,并使用它同步并允许你的异步初始化在需要时懒散地发生吗?

public class MySingleton {
   private bool initialized=false;
   private SemaphoreSlim mutex = new SemaphoreSlim(1, 1);
   public async Task DoStuff() {
       if (!initialized) {
           await mutex.WaitAsync();
           try {
               if (!initialized) {
                   await InitAsync();
                   initialized = true;
               }
           } finally {
               mutex.Release();
           }
       }
       DoTheRealStuff();
   }
   private async Task InitAsync() {
       await Stuff();
   }
}

答案 2 :(得分:0)

使用Microsoft.VisualStudio.Threading NuGet包,然后像这样设计你的类:

public class Singleton {

  private static readonly AsyncLazy<Singleton> instance =
      new AsyncLazy<Singleton>( CreateAndDoSomething );

  private Singleton() {
  }

  // This method could also be an async lambda passed to the AsyncLazy constructor.
  private static async Task<Singleton> CreateAndDoSomething() {
     var ret = new Singleton();
     await ret.InitAsync();
     return ret;
  }

  private async Task InitAsync() {
     await Stuff();
  }

  public static AsyncLazy<Singleton> Instance
  {
     get { return instance; }
  }
}

用法:

Singleton singleton = Singleton.Instance;

更多关于Asynchronous Lazy Initialization

答案 3 :(得分:0)

看起来您遇到的问题是构造函数不能具有异步修饰符。如果是这种情况,您可以执行以下操作。如果没有,请详细说明。

    public MySingleton()
    {
        InitAsync().Wait();
    }

您可以探索的另一件事是尝试使用双重检查锁定模式(DCLP)。如果将如下 -

private volatile object _sync = new Object();

if (!_init) 
{
    lock (_sync) 
    { 
        if (!_init) 
        { 
        }
     }
}

C#/ .Net支持此功能。您应该在interwebs上找到更多对此的引用。