如何监视/等待对象数组

本文关键字:等待 对象 数组 监视 何监视 | 更新日期: 2023-09-27 18:08:52

我使用并发包来存储一组对象。我想实现这样的东西如果(一个对象存在)返回它否则等待直到其中一个获得自由,如果在特定时间内没有获得自由则抛出异常。

if(对象已返回)添加到包

我想使用监视器,但监视器可以等待一个特定的对象。我想等到他们有空的时候。我该如何实现它?

如何监视/等待对象数组

扩展msdn示例:

public class FiniteObjectPool<T>: IDisposable
{
    System.Threading.AutoResetEvent m_Wait = new System.Threading.AutoResetEvent(false);
    private ConcurrentBag<T> _objects;
    public FiniteObjectPool()
    {
        _objects = new ConcurrentBag<T>();
    }
    public T GetObject()
    {
        T item;
        while(!_objects.TryTake(out item))
        {
            m_Wait.WaitOne(); //an object was not available, wait until one is
        }
        return item;
    }
    public void PutObject(T item)
    {
        _objects.Add(item);
        m_Wait.Set(); //signal a waiting thread that object may now be available
    }
    public void Dispose()
    {
        m_Wait.Dispose();
    }
}

EDIT -使用'Context'习语包装器的示例

class Program
{
    public class FiniteObjectPoolContext<T>: IDisposable
    {
        FiniteObjectPool<T> m_Pool = new FiniteObjectPool<T>();
        public T Value { get; set; }
        public FiniteObjectPoolContext(FiniteObjectPool<T> pool)
        {
            m_Pool = pool;
            Value = pool.GetObject(); //take an object out - this will block if none is available
        }
        public void Dispose()
        {
            m_Pool.PutObject(Value); //put the object back because this context is finished
        }
    }
    static void Main(string[] args)
    {
        FiniteObjectPool<int> pool = new FiniteObjectPool<int>();
        for (int i = 0; i < 10; i++)
        {
            pool.PutObject(i);
        }
        List<Task> tasks = new List<Task>();
        for (int i = 0; i < 20; i++)
        {
            int id = i;
            tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine("Running task " + id);
                    using (var con = new FiniteObjectPoolContext<int>(pool))
                    {
                        Console.WriteLine("Task " + id + " got object from pool: " + con.Value);
                        System.Threading.Thread.Sleep(5000);
                        Console.WriteLine("Task " + id + " is finished with pool object: " + con.Value);
                    }
                }));
        }
        Task.WaitAll(tasks.ToArray());
        Console.WriteLine("DONE");
        Console.ReadLine();
    }
}

注意线程同步机制注入的延迟。

为你想做的操作尝试信号量。. net有两种信号量实现。Semaphore和SemaphoreSlim,都可以用来实现多个线程试图访问一个资源池