ホームページ >バックエンド開発 >C++ >C# で非同期初期化を確実に 1 回実行するにはどうすればよいですか?

C# で非同期初期化を確実に 1 回実行するにはどうすればよいですか?

DDD
DDDオリジナル
2025-01-13 22:03:44404ブラウズ

How to Ensure Single Execution of Asynchronous Initialization in C#?

C# での非同期初期化の単一実行の保証

この記事では、複数のスレッドからの同時呼び出しであっても、InitializeAsync() メソッドを介したクラスの非同期初期化が 1 回だけ実行されるようにするという課題に取り組みます。

1 つのアプローチでは、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>

より洗練されたソリューションは 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>

使用例:

<code class="language-csharp">private AsyncLazy<bool> asyncLazy = new AsyncLazy<bool>(async () =>
{
    await DoStuffOnlyOnceAsync();
    return true;
});</code>

注: DoStuffOnlyOnceAsync() には戻り値の型がないため、ブール型のプレースホルダーが使用されます。

洗練された AsyncLazy<T> 実装については、Stephan Cleary のブログ投稿を参照してください: https://www.php.cn/link/366c0196895c9eeaa75992bacac60426

以上がC# で非同期初期化を確実に 1 回実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。