可重用资源的等待集合

问题描述 投票:0回答:1

我尝试在网上搜索此内容,但没有找到我想要的内容。

我有一份执行某些工作的工人名单。为了执行这项工作,工作人员需要访问资源。所以我需要一个线程安全的集合来管理对资源的访问。资源是可重用的,但一次只能由 1 个任务访问。这是一个非常简单的例子,说明了它是如何工作的。

当我试图想出一种线程安全的方式来做到这一点时,我的思绪在转圈。

public interface IResource
{
}

public class TestResource : IResource
{
    public void Print()
    {
        Console.WriteLine("printing");
    }
}

public class ResourcePool
{
    public async Task TryUseResource<T>(Action<T> callback,
        CancellationToken token = default) where T : IResource
    {
        // await and claim a resource that is not in use. 
        // execute the callback
        // unclaim the resource
    }
}

public class Worker
{
    public async void ExecuteWork(ResourcePool pool)
    {
        await pool.TryUseResource<TestResource>((resource) =>
        {
            resource.Print();
        });
    }
}
c# asynchronous async-await collections thread-safety
1个回答
-1
投票

我想出了以下内容:

    public class AwaitableResources<T>
    {
        private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0);
        private readonly ConcurrentQueue<T> availableResources = new ConcurrentQueue<T>();
        public async Task<bool> TryUseResource(Action<T> callback, CancellationToken token = default)
        {
            await semaphore.WaitAsync(token);
            bool success = false;
            try
            {
                if(availableResources.TryDequeue(out var resource))
                {
                    try
                    {
                        callback.Invoke(resource);
                        success = true;
                    }
                    finally
                    {
                        availableResources.Enqueue(resource);
                    }
                }
            }
            finally
            {
                semaphore.Release();
            }

            if (token.IsCancellationRequested)
                success = false;
            return success;
        }
    }

© www.soinside.com 2019 - 2024. All rights reserved.