>백엔드 개발 >C++ >C#에서 비동기 잠금으로 간헐적인 파일 액세스 오류를 방지하는 방법은 무엇입니까?

C#에서 비동기 잠금으로 간헐적인 파일 액세스 오류를 방지하는 방법은 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2025-01-15 06:03:44814검색

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.