首页 >后端开发 >C++ >C#中如何保证异步初始化的单次执行?

C#中如何保证异步初始化的单次执行?

DDD
DDD原创
2025-01-13 22:03:44407浏览

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

保证 C# 中异步初始化的单次执行

本文解决了通过其 InitializeAsync() 方法确保类的异步初始化仅执行一次的挑战,即使来自多个线程的并发调用也是如此。

一种方法使用 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#中如何保证异步初始化的单次执行?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn