0

我不确定为什么这段代码不安全。我有一个测试用例来证明它不安全。

        List<T> _l = new List<T>();
        public void Add(T t)
        {
            lock (_l)
            {
                _l.Add(t);
                Monitor.PulseAll(_l);
            }
        }
        public T[] RemoveToArray(TimeSpan timeout)
        {
            lock (_l)
            {
                if (_l.Count == 0)
                {
                    bool timedout = !Monitor.Wait(_l, timeout);

                    // no lock 
                    if (timedout)
                    {
                        return new T[0];
                    }
                }
                // with lock
                T[] items = _l.ToArray();
                _l.Clear();
                return items;
            }
        }

该函数应该等待一段时间(之后超时)以使新项目到达。当时间到时,返回一个空数组,否则将内部列表中的所有元素排到一个数组中。在测试代​​码中,我创建了两个Task,一个用来添加,另一个用来移除。

        times = 3;
        Task[] tasks = new Task[2];
        tasks[0] = Task.Factory.StartNew(() =>
        {
            firstRemoveItems = _l.RemoveToArray(_infinite);
            Util.Delay(TimeSpan.FromMilliseconds(10)).Wait();
            secondRemoveItems = _l.RemoveToArray(_infinite);
        });
        tasks[1] = Task.Factory.StartNew(() =>
        {
            _l.Add(new object());
            Util.Delay(TimeSpan.FromMilliseconds(5)).Wait();
            for (int i = 1; i < times; i++)                
                _l.Add(new object());
        });

添加了三个项目,但是,项目的总数是 2、3、4。我不太确定问题是什么。我假设等待超时后重新获取锁?

4

0 回答 0