Maison >développement back-end >C++ >Comment garantir une exécution unique de l'initialisation asynchrone en C# ?
Garantir l'exécution unique de l'initialisation asynchrone en C#
Cet article aborde le défi consistant à garantir que l'initialisation asynchrone d'une classe, via sa méthode InitializeAsync()
, ne s'exécute qu'une seule fois, même avec des appels simultanés de plusieurs threads.
Une approche utilise SemaphoreSlim
:
<code class="language-csharp">public class MyService : IMyService { private readonly SemaphoreSlim mSemaphore = new SemaphoreSlim(1, 1); private bool mIsInitialized; public async Task InitializeAsync() { if (!mIsInitialized) { await mSemaphore.WaitAsync(); if (!mIsInitialized) { await DoStuffOnlyOnceAsync(); mIsInitialized = true; } mSemaphore.Release(); } } private Task DoStuffOnlyOnceAsync() { return Task.Run(() => { Thread.Sleep(10000); }); } }</code>
Une solution plus élégante exploite AsyncLazy<T>
:
<code class="language-csharp">public class AsyncLazy<T> : Lazy<Task<T>> { public AsyncLazy(Func<T> valueFactory) : base(() => Task.Run(valueFactory)) { } public AsyncLazy(Func<Task<T>> taskFactory) : base(() => Task.Run(() => taskFactory())) { } public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); } }</code>
Exemple d'utilisation :
<code class="language-csharp">private AsyncLazy<bool> asyncLazy = new AsyncLazy<bool>(async () => { await DoStuffOnlyOnceAsync(); return true; });</code>
Remarque : un espace réservé booléen est utilisé car DoStuffOnlyOnceAsync()
n'a pas de type de retour.
Pour une implémentation AsyncLazy<T>
raffinée, référez-vous au billet de blog de Stephan Cleary : https://www.php.cn/link/366c0196895c9eeaa75992bacac60426
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!