Como inicializar um objeto usando o padrão async-await

Estou tentando seguir o padrão RAII em minhas classes de serviço, o que significa que quando um objeto é construído, ele é totalmente inicializado. No entanto, estou enfrentando dificuldades com APIs assíncronas. A estrutura da classe em questão parece seguir

class ServiceProvider : IServiceProvider // Is only used through this interface
{
    public int ImportantValue { get; set; }
    public event EventHandler ImportantValueUpdated;

    public ServiceProvider(IDependency1 dep1, IDependency2 dep2)
    {
        // IDependency1 provide an input value to calculate ImportantValue
        // IDependency2 provide an async algorithm to calculate ImportantValue
    }
}

Eu também estou alvejando para se livrar de efeitos colaterais emImportantValue getter, para torná-lo thread-safe.

Agora usuários deServiceProvider vai criar uma instância dele, inscreva-se em um evento deImportantValue mudar e obter a inicialImportantValue. E aí vem o problema, com o valor inicial. Desde oImportantValue é calculado de forma assíncrona, a classe não pode ser totalmente inicializada no construtor. Não há problema em ter esse valor como nulo inicialmente, mas eu preciso ter um lugar onde ele será calculado pela primeira vez. Um lugar natural para isso poderia ser oImportantValueÉ getter, mas eu estou alvejando para torná-lo thread-safe e sem efeitos colaterais.

Então, basicamente, estou preso a essas contradições. Você poderia por favor me ajudar e oferecer alguma alternativa? Ter valor inicializado no construtor enquanto bom não é realmente necessário, mas sem efeitos colaterais e thread-segurança de propriedade é obrigatória.

Desde já, obrigado.

EDITAR: Mais uma coisa para adicionar. Estou usando o Ninject para instanciação e, até onde eu entendo, ele não suporta métodos assíncronos para criar uma ligação. Embora a abordagem com o início de alguma operação baseada em tarefa no construtor funcione, não posso aguardar seu resultado.

Ou seja duas próximas abordagens (oferecidas como respostas até o momento) não serão compiladas, já que Tarefa é retornada, não meu objeto:

Kernel.Bind<IServiceProvider>().ToMethod(async ctx => await ServiceProvider.CreateAsync())

ou

Kernel.Bind<IServiceProvider>().ToMethod(async ctx => 
{
    var sp = new ServiceProvider();
    await sp.InitializeAsync();
})

A ligação simples funcionará, mas não estou aguardando o resultado da inicialização assíncrona iniciada no construtor, conforme proposto por Stephen Cleary:

Kernel.Bind<IServiceProvider>().To<ServiceProvider>();

... e isso não parece bom para mim.

questionAnswers(5)

yourAnswerToTheQuestion