ホームページ > バックエンド開発 > C++ > C# の非同期ロックで断続的なファイル アクセス エラーを回避するにはどうすればよいですか?

C# の非同期ロックで断続的なファイル アクセス エラーを回避するにはどうすればよいですか?

Patricia Arquette
リリース: 2025-01-15 06:03:44
オリジナル
812 人が閲覧しました

How to Avoid Intermittent File Access Errors with Asynchronous Locking in C#?

C# の非同期ロックを使用した断続的なファイル アクセス エラーの解決

非同期ロック、特にハッシュされた URL や AsyncDuplicateLock のようなクラスを使用する場合、断続的なファイル アクセス エラーが発生することがあります。 これは多くの場合、同時ディクショナリ内でのセマフォの不適切な処理が原因で発生します。 初期の欠陥のあるアプローチは次のようになります:

<code class="language-csharp">SemaphoreSlim locker;
if (SemaphoreSlims.TryRemove(s, out locker))
{
    locker.Release();
    locker.Dispose();
}</code>
ログイン後にコピー

ここでの問題は、セマフォを解放するに削除することです。これにより、セマフォの過剰なチャーンが発生し、辞書から削除された後もセマフォが使用され続けることになります。

堅牢なソリューションでは、参照カウントを使用してセマフォの有効期間を管理します。

<code class="language-csharp">public sealed class AsyncDuplicateLock
{
    private sealed class RefCounted<T>
    {
        public RefCounted(T value)
        {
            RefCount = 1;
            Value = value;
        }

        public int RefCount { get; set; }
        public T Value { get; private set; }
    }

    private static readonly Dictionary<object, RefCounted<SemaphoreSlim>> SemaphoreSlims
                        = new Dictionary<object, RefCounted<SemaphoreSlim>>();

    private SemaphoreSlim GetOrCreate(object key)
    {
        RefCounted<SemaphoreSlim> item;
        lock (SemaphoreSlims)
        {
            if (SemaphoreSlims.TryGetValue(key, out item))
            {
                ++item.RefCount;
            }
            else
            {
                item = new RefCounted<SemaphoreSlim>(new SemaphoreSlim(1, 1));
                SemaphoreSlims[key] = item;
            }
        }
        return item.Value;
    }

    public IDisposable Lock(object key)
    {
        GetOrCreate(key).Wait();
        return new Releaser { Key = key };
    }

    public async Task<IDisposable> LockAsync(object key)
    {
        await GetOrCreate(key).WaitAsync().ConfigureAwait(false);
        return new Releaser { Key = key };
    }

    private sealed class Releaser : IDisposable
    {
        public object Key { get; set; }

        public void Dispose()
        {
            RefCounted<SemaphoreSlim> item;
            lock (SemaphoreSlims)
            {
                item = SemaphoreSlims[Key];
                --item.RefCount;
                if (item.RefCount == 0)
                    SemaphoreSlims.Remove(Key);
            }
            item.Value.Release();
        }
    }
}</code>
ログイン後にコピー

この改訂されたコードは、RefCounted<T> ラッパーを使用してセマフォ参照を追跡します。 セマフォは参照カウントが 0 に達した場合にのみディクショナリから削除されるため、適切な解放が確保され、早期の破棄が防止され、断続的なファイル アクセス エラーが排除されます。

以上がC# の非同期ロックで断続的なファイル アクセス エラーを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート