Singleton类,需要一些异步调用 [英] Singleton Class which requires some async call

查看:51
本文介绍了Singleton类,需要一些异步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Singleton类,该类加载有关其构造的一些数据.问题在于,加载此数据需要调用 async 方法,但是构造函数不能为 async .

I have a Singleton Class which loads some data on its construction. The problem is that loading this data requires calling async methods, but the constructor cannot be async.

换句话说,我的班级具有以下结构:

In other words, my class has following structure:

public class Singleton
{
   private static Singleton instance;

   private Singleton() 
   {
       LoadData();
   }

   public static Singleton Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
       }
    }
}

LoadData()是一个 async 函数,它调用许多 async 函数以及初始化.如何正确调用 LoadData(),以便一切都能正确初始化?

LoadData() is an async function which calls lots of async functions as well as initialization. How can I call LoadData() properly so everything initialize correctly?

推荐答案

问题是加载此数据需要调用异步方法,但是构造函数不能异步.

The problem is that loading this data requires calling async methods, but the constructor cannot be async.

虽然不能使构造函数本身异步,但可以 从构造函数内部调用异步方法.您只是不会立即得到结果.

While you can't make the constructor itself asynchronous, you can call asynchronous methods from within the constructor. You just will not get the results back immediately.

提供的异步方法返回 Task Task< T> ,一旦异步操作完成,您就可以始终在任务上使用延续来在类中设置数据,或仅屏蔽结果,具体取决于您的方案中最有意义的内容.在不了解构造此对象的要求的情况下,很难知道在这种情况下什么是合适的.

Provided the asynchronous methods return Task or Task<T>, you can always use a continuation on the task to set your data within the class once the asynchronous operation completes, or just block on the results, depending on what makes the most sense in your scenario. Without knowing the requirements for construction of this object, it's difficult to know what is appropriate in this scenario.

鉴于上述目标,一个选择是更改您的 Singleton 声明,以便检索 Instance 的方法是方法,而不是属性.这将使您使其异步:

One option, given the goals listed above, would be to change your Singleton declaration so that method to retrieve the Instance was a method, not a property. This would allow you to make it asynchronous:

public class Singleton
{
   private static Singleton instance;

   private Singleton() 
   {
          // Don't load the data here - will be called separately
   }

   public static async Task<Singleton> GetInstance()
   {
         if (instance == null)
         {
            instance = new Singleton();
            await instance.LoadData();
         }

         return instance;
    }
}

这将允许您在调用上使用 await 来实际检索实例.这样做的好处是,它确实使您清楚地知道正在调用异步操作,并且可以正确处理结果,因为结果将像其他异步方法一样返回.

This would allow you to use await on the call to actually retrieve the instance. The nice thing about this is that it does make it very clear that you're calling an asynchronous operation, and you will get proper handling of the results, as the result will come back like any other async method.

但是请注意,这不是线程安全的(尽管原始线程也不是),因此,如果要在多个线程中使用此Singleton,则可能必须重新考虑整体设计.

Be aware, however, that this isn't thread safe (though the original wasn't either), so if you're going to use this Singleton from multiple threads, you may have to rethink the overall design.

另一个选择是使您的 Singleton 类不自动加载数据.相反,使从类检索数据的方法异步.这提供了一些实际的优势,因为使用情况可能更标准,并且与使您能够处理多个线程相比,您可以更轻松地支持来自多个线程的调用(因为您可以控制数据加载过程).异步访问类实例.

The other option would be to make your Singleton class not automatically load data. Make the methods that retrieve the data from the class asynchronous, instead. This provides some real advantages, as the usage is probably a bit more standard, and you can support calls from multiple threads a bit more easily (since you can control the data loading process) than you'd be able to handle it with making the access of the class instance asynchronous.

这篇关于Singleton类,需要一些异步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆