Вопрос по многопоточности
От: e.thrash  
Дата: 30.10.15 07:06
Оценка:
Есть класс по работе с кэшом.
Один метод получает данные из базы и сохраняет их в кеше LoadCache — один объект в кэше для всех клиентов.
Второй возвращает этот объект клиентам GetData().
Сейчас сделал так, но понимаю, что что-то не так.

  class Program
    {        
        static AutoResetEvent resetEvent = new AutoResetEvent(false);
        static bool isInitialized = false;
        
        static void Main(string[] args)
        {
            Console.ReadKey();
        }

        static Object GetData()
        {
            if (!isInitialized)
            {
                resetEvent.WaitOne(new TimeSpan(0, 5, 0));
            }
            return Cache["test"] as Object;
        }

        static void LoadCache()
        {
            try
            {
                var data = LoadData();
                LoadCache["test"] = data;
                resetEvent.Set();
            }
            finally
            {
                isInitialized = true;
            }            
        }
    }
Re: Вопрос по многопоточности
От: Sinix  
Дата: 30.10.15 07:25
Оценка: +2 :))
Здравствуйте, e.thrash, Вы писали:

ET>Один метод получает данные из базы и сохраняет их в кеше LoadCache — один объект в кэше для всех клиентов.

Use Task<T>, Luke!
А для приведённого примера вообще не надо возиться с многопоточностью, достаточно Lazy<T>.

ET>Сейчас сделал так, но понимаю, что что-то не так.

LoadCache было бы неплохо запускать

P.S.
1. isInitialized как volatile объявлять надо.
2. lock использовать для данных разделяемых должен ты.
3. isInitialized = true в finally? Лёгких путей ищешь, путь к стороне тёмной этот ведёт. Упал код если — что будет?
Re[2]: Вопрос по многопоточности
От: e.thrash  
Дата: 30.10.15 07:57
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, e.thrash, Вы писали:


ET>>Один метод получает данные из базы и сохраняет их в кеше LoadCache — один объект в кэше для всех клиентов.

S>Use Task<T>, Luke!
S>А для приведённого примера вообще не надо возиться с многопоточностью, достаточно Lazy<T>.

LoadCache работает долго, я его запускаю при старте приложения, пока пользователь попадет на нужную страницу, LoadCache уже загрузится.
Или вы другое имеете ввиду про Lazy<T>? он же вроде синхронно работает

ET>>Сейчас сделал так, но понимаю, что что-то не так.

S>LoadCache было бы неплохо запускать

накидал упрощенный пример, а так он запускается))

S>P.S.

S>2. lock использовать для данных разделяемых должен ты.

а где в моем примере еще нужен Lock? на чтение?

S>3. isInitialized = true в finally? Лёгких путей ищешь, путь к стороне тёмной этот ведёт. Упал код если — что будет?


согласен, криво получилось. удалил finally
Re[3]: Вопрос по многопоточности
От: Sinix  
Дата: 30.10.15 08:23
Оценка: 4 (1)
Здравствуйте, e.thrash, Вы писали:

ET>LoadCache работает долго, я его запускаю при старте приложения, пока пользователь попадет на нужную страницу, LoadCache уже загрузится.

В пруфкоде этого нет

ET>Или вы другое имеете ввиду про Lazy<T>? он же вроде синхронно работает.

Так задачу надо целиком озвучивать
Для вашей уже изобретён TaskCompletionSource.

ET>а где в моем примере еще нужен Lock? на чтение?

В конкретно исходном примере — нужен. Нет никаких проверок, что LoadCache() не запустится дважды.
Re: Вопрос по многопоточности
От: Vladek Россия Github
Дата: 30.10.15 12:43
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть класс по работе с кэшом.

ET>Один метод получает данные из базы и сохраняет их в кеше LoadCache — один объект в кэше для всех клиентов.
ET>Второй возвращает этот объект клиентам GetData().

Я так понял, пример отсюда — то, что вам нужно.
http://files.rsdn.org/43395/hr-kyle-theisen-04.png
Re: Вопрос по многопоточности
От: koodeer  
Дата: 31.10.15 13:13
Оценка: 38 (1) +1
Здравствуйте, e.thrash, Вы писали:

ET>Есть класс по работе с кэшом.


Возможно, подойдёт асинхронный кэш, описанный в этом документе (автор Stephen Toub), страница 27. Сделан на тасках и Lazy<T>, как предлагает Sinix.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.