Comment initialiser un objet à l'aide asynchrone attendent modèle

Je suis en train de suivre RAII dans ma classes de service, ce qui signifie que lorsqu'un objet est construit, il est complètement initialisé. Cependant, je suis confronté à des difficultés avec des Api asynchrones. La structure de la classe en question ressemble à ce qui suit

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

Je suis également visant à se débarrasser des effets secondaires ImportantValue de lecture, pour en faire thread-safe.

Maintenant, les utilisateurs de ServiceProvider va créer une instance de celle-ci, s'inscrire à un événement de ImportantValue changement, et d'obtenir la première ImportantValue. Et c'est là le problème, avec la valeur initiale. Depuis le ImportantValue est calculé de manière asynchrone, la classe ne peut pas être entièrement initialisé dans le constructeur. C'est peut-être bien d'avoir une valeur nulle au départ, mais ensuite j'ai besoin d'avoir un endroit où il sera calculé première fois. Un endroit naturel pour que pourrait être le ImportantValue's de lecture, mais je suis ciblage pour le rendre thread-safe et sans effets secondaires.

Donc, je suis tout bonnement avec ces contradictions. Pourriez-vous svp m'aider et offrir des alternatives? Avoir de la valeur initialisée dans le constructeur, tandis que nice n'est pas vraiment nécessaire, mais pas d'effets secondaires et fil-sécurité des biens est obligatoire.

Merci d'avance.

EDIT: Une chose de plus à ajouter. Je suis en utilisant Ninject pour l'instanciation, et comme je le comprends, il ne supporte pas les méthodes asynchrones pour créer une liaison. Alors que l'approche de lancer une Tâche de base de fonctionnement dans le constructeur de travail, je ne peux pas attendre son résultat.

I. e. deux approches suivantes (offert en guise de réponses à ce jour) ne compile pas, étant donné que la Tâche est retourné, c'est pas mon objet:

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

ou

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

Liaison Simple de fonctionner, mais je ne suis pas attendre le résultat de l'initialisation asynchrone a commencé dans le constructeur, tel que proposé par Stephen Cleary:

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

... et ce n'est pas très bon pour moi.

Je ne pense pas que le RAII. Probablement la partie la plus importante est la désallocation de la ressource (bien que le nom ne suggère pas que). Et qui ne s'applique pas à C#, car GC causes de non-déterministe de libération de la mémoire.
Découvrez ma bibliothèque AsyncContainer

OriginalL'auteur Haspemulator | 2013-04-09