Cómo inicializar un objeto usando el patrón async-await

Estoy intentando seguir el patrón RAII en mis clases de servicio, lo que significa que cuando se construye un objeto, se inicializa por completo. Sin embargo, estoy enfrentando dificultades con las API asíncronas. La estructura de la clase en cuestión se parece a la siguiente

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

También estoy apuntando a deshacerme de los efectos secundarios enImportantValue getter, para que sea seguro para la rosca.

Ahora los usuarios deServiceProvider creará una instancia de la misma, suscribirse a un evento deImportantValue cambiar, y obtener la inicialImportantValue. Y aquí viene el problema, con el valor inicial. Desde elImportantValue se calcula de forma asíncrona, la clase no se puede inicializar completamente en el constructor. Puede estar bien tener este valor como nulo inicialmente, pero luego necesito tener un lugar donde se calcule la primera vez. Un lugar natural para eso podría ser elImportantValueestá a punto de hacerlo, pero estoy apuntando a que sea seguro para los hilos y sin efectos secundarios.

Así que básicamente estoy atrapado con estas contradicciones. ¿Podría por favor ayudarme y ofrecer alguna alternativa? Tener el valor inicializado en el constructor, aunque agradable, no es realmente necesario, pero no es obligatorio el uso de efectos secundarios y la seguridad de la propiedad.

Gracias por adelantado.

EDITAR: Una cosa mas que agregar. Estoy usando Ninject para la creación de instancias y, por lo que entiendo, no admite métodos asíncronos para crear un enlace. Si bien el enfoque con el inicio de una operación basada en tareas en el constructor funcionará, no puedo esperar su resultado.

Es decir. los dos enfoques siguientes (ofrecidos como respuestas hasta ahora) no se compilarán, ya que la tarea se devuelve, no mi objeto:

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

o

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

El enlace simple funcionará, pero no estoy esperando el resultado de la inicialización asíncrona iniciada en el constructor, como lo propone Stephen Cleary:

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

... y eso no se ve bien para mí.

Respuestas a la pregunta(5)

Su respuesta a la pregunta