Как обеспечить потокобезопасную страницу ASP.net для доступа к статическому списку объектов - PullRequest
3 голосов
/ 23 ноября 2011

В моем веб-приложении у меня есть общий список объектов для всех пользователей в сети.

public static List<MyClass> myObjectList = new List<MyClass>();

, поэтому, когда несколько пользователей в сети пытаются прочитать данные из этого объекта myObjectList тогда есть ли вероятность проблемы синхронизации потока .

В другом сценарии несколько пользователей читают из myObjectList , и немногие из них также пишут, но каждый пользователь пишет по своему индексу Списка.Каждый пользователь может добавить новый элемент в этот список.Так что теперь я думаю, что есть вероятность проблема синхронизации .

Как написать потокобезопасный служебный класс, который может читать и записывать данные из этого объекта более безопасным способом.

Предложения приветствуются

Код, предложенный Angelo, выглядит следующим образом

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;


namespace ObjectPoolExample
{
    public class ObjectPool<T>
    {
        private ConcurrentBag<T> _objects;
        private Func<T> _objectGenerator;

        public ObjectPool(Func<T> objectGenerator)
        {
            if (objectGenerator == null) throw new ArgumentNullException("objectGenerator");
            _objects = new ConcurrentBag<T>();
            _objectGenerator = objectGenerator;
        }

        public T GetObject()
        {
            T item;
            if (_objects.TryTake(out item)) return item;
            return _objectGenerator();
        }

        public void PutObject(T item)
        {
            _objects.Add(item);
        }
    }

    class Program
    {
       static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            // Create an opportunity for the user to cancel.
            Task.Factory.StartNew(() =>
                {
                    if (Console.ReadKey().KeyChar == 'c' || Console.ReadKey().KeyChar == 'C')
                        cts.Cancel();
                });

            ObjectPool<MyClass> pool = new ObjectPool<MyClass> (() => new MyClass());            

            // Create a high demand for MyClass objects.
            Parallel.For(0, 1000000, (i, loopState) =>
                {
                    MyClass mc = pool.GetObject();
                    Console.CursorLeft = 0;
                    // This is the bottleneck in our application. All threads in this loop
                    // must serialize their access to the static Console class.
                    Console.WriteLine("{0:####.####}", mc.GetValue(i));                 

                    pool.PutObject(mc);
                    if (cts.Token.IsCancellationRequested)
                        loopState.Stop();                 

                });
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
        }

    }

    // A toy class that requires some resources to create.
    // You can experiment here to measure the performance of the
    // object pool vs. ordinary instantiation.
    class MyClass
    {
        public int[] Nums {get; set;}
        public double GetValue(long i)
        {
            return Math.Sqrt(Nums[i]);
        }
        public MyClass()
        {
            Nums = new int[1000000];
            Random rand = new Random();
            for (int i = 0; i < Nums.Length; i++)
                Nums[i] = rand.Next();
        }
    }   
}

Я думаю, что я могу пойти с этим подходом.

1 Ответ

3 голосов
/ 23 ноября 2011

Если вы используете .NET 4.0, вам лучше перейти на одну из поточно-безопасных коллекций , уже поддерживаемую средой выполнения, например, ConcurrentBag.

Параллельная сумка, однако, не поддерживает доступ по индексу, если я правильно помню, поэтому вам может потребоваться прибегнуть к ConcurrentDictionary, если вам нужен доступ к объекту по заданному ключу.

Если .NET 4.0 не подходит, вы должны прочитать следующее сообщение в блоге:

Почему коллекции с защитой потоков настолько сложны?

...