Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Mengelakkan Ralat Akses Fail Bersekala dengan Penguncian Asynchronous dalam C#?

Bagaimana untuk Mengelakkan Ralat Akses Fail Bersekala dengan Penguncian Asynchronous dalam C#?

Patricia Arquette
Lepaskan: 2025-01-15 06:03:44
asal
913 orang telah melayarinya

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

Menyelesaikan Ralat Akses Fail Selang-seli dengan Penguncian Asynchronous dalam C#

Penguncian tak segerak, terutamanya apabila menggunakan URL cincang dan kelas seperti AsyncDuplicateLock, kadangkala boleh membawa kepada ralat akses fail yang terputus-putus. Ini selalunya berpunca daripada pengendalian semafor yang tidak betul dalam kamus serentak. Pendekatan awal yang cacat mungkin kelihatan seperti ini:

SemaphoreSlim locker;
if (SemaphoreSlims.TryRemove(s, out locker))
{
    locker.Release();
    locker.Dispose();
}
Salin selepas log masuk

Masalah di sini ialah mengalih keluar semaphore sebelum melepaskannya. Ini mewujudkan pergolakan semaphore yang berlebihan, yang membawa kepada penggunaan semaphore yang berterusan walaupun selepas dialih keluar daripada kamus.

Penyelesaian teguh menggunakan pengiraan rujukan untuk menguruskan jangka hayat semaphore:

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();
        }
    }
}
Salin selepas log masuk

Kod yang disemak ini menggunakan pembungkus RefCounted<T> untuk menjejak rujukan semaphore. Semaphore hanya dialih keluar daripada kamus apabila bilangan rujukannya mencapai sifar, memastikan pelepasan yang betul dan mencegah pelupusan pramatang, dengan itu menghapuskan ralat akses fail yang terputus-putus.

Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Ralat Akses Fail Bersekala dengan Penguncian Asynchronous dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan