powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как "залочить" весь класс?
20 сообщений из 20, страница 1 из 1
Как "залочить" весь класс?
    #39996511
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть разделяемый ресурс, для работы с которым хочу создать отдельный класс. Чтобы не было конфликтов в многопоточном приложении, буду применять lock.

Вопрос как лучше сделать? Оборачивать тело каждого метода в lock:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
public static class myclass
    {
        static object lobg = new object();

        static void method1(int param)
        {
            lock (lobg)
            {
                //code
            }
        }
        static void method2(string param)
        {
            lock (lobg)
            {
                //code
            }
        }
    } 



Или есть более изящные решения, автоматически лочащие все методы класса?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996584
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql
Или есть более изящные решения, автоматически лочащие все методы класса?


Декоратор + прокси.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996591
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996599
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так не стоит делать, но кого это останавливало...

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
[Synchronization]
public static class myclass
{
    static void method1(int param)
    {
        //code
    }
    static void method2(string param)
    {
        //code
    }
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public static class myclass
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    static void method1(int param)
    {
        //code
    }

    [MethodImpl(MethodImplOptions.Synchronized)]
    static void method2(string param)
    {
        //code
    }
}
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996606
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
следующая тема автора: как найти дедлок :D
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996615
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
[Synchronization]
public static class myclass


А так точно сработает? Мало нашел по сабжу, но пишут что класс к тому же должен быть унаследован от ContextBoundObject.

Вроде как:

Код: c#
1.
2.
[Synchronization]
public static class myclass : ContextBoundObject


или не обязательно?

Если я правильно понял - первый вариант блочит все методы, если поток пользуется хотябы одним из них, а второй вариант - методы по отдельности? т.е. когда один поток юзает метод1, второй поток может спокойно юзать метод2?

ЗЫ. где тут можно словить дедлок, если потоки не зависят друг от друга, обрабатывают свою порцию данных каждый... И ерунда может произойти наверное только если ресурс физически исчезнет...
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996692
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то оно не работает - вот на таком примере лезут и единицы и двойки, хотя по идее должны по очереди

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
  class Program
    {
        static void Main(string[] args)
        {
            Task.Run(() => { myclass.method("1"); });
            Task.Run(() => { myclass.method("2"); });
            Console.ReadLine();
        }

    }

  
    [Synchronization]
   public static class myclass 
    {
        public static void method(string param)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(param);
            }
        }

    }




Так вроде работает. Но мало чем отличается от того чтоб каждый метод в lock оборачивать.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
    class Program
    {
        static object l = new object();
        static void Main(string[] args)
        {

            Task.Run(() => { myclass.method1("1"); });
            Task.Run(() => { myclass.method2("2"); });
            Console.ReadLine();
        }

    }

    public static  class myclass 
    {
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void method1(string param)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(param);
            }
        }
        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void method2(string param)
        {
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(param);
            }
        }
    }
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996753
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql,

ну гляньте сюда ещё:

https://github.com/Fody/MethodDecorator

если скажете какую задачу решаете, зачем, может болше сможем помочь
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996906
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
если скажете какую задачу решаете, зачем, может болше сможем помочь


Да задача то примитивная - писать в базу sqlite. Мне показалось проще понаставить локов, чем отлавливать исключения "база занята" и делать повторные попытки...

Ну и так, для общего развития - мож еще зачем пригодится когда-нибудь..
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996925
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql,
можно пример, в какой ситуации для записи в базу потребовались локи?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996937
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub
iskatelsql,
можно пример, в какой ситуации для записи в базу потребовались локи?

Можно погуглить по "SQLite database is locked".

sqlite однопоточная по крайней мере реализация System.Data.SQLite , если транзакция продлится больше таймаута (в своей глянул busy_timeout 3000 , наверное дефолтный), остальные все запросы на подключение вылетят с ошибкой. и тут либо таймаут выкручивать (моя паранойя подсказывает что где - то на тысячелетие :)) либо локи, либо чтото вроде

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 while(true)
            {
                try
                {
                    //connect
                    break;
                }
                catch (Exception)
                {
                    Sleep(100);
                }
            }


Что тоже не эстетично.

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

Так то по разному можно сделать... я вот локи выбрал.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996949
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql
vb_sub
iskatelsql,
можно пример, в какой ситуации для записи в базу потребовались локи?

Можно погуглить по "SQLite database is locked".

sqlite однопоточная по крайней мере реализация System.Data.SQLite , если транзакция продлится больше таймаута (в своей глянул busy_timeout 3000 , наверное дефолтный), остальные все запросы на подключение вылетят с ошибкой. и тут либо таймаут выкручивать (моя паранойя подсказывает что где - то на тысячелетие :)) либо локи, либо чтото вроде
...

Таймаут бесполезно увеличивать. В SQLite можно дэдлок словить даже в один поток 21957488

В SQLite подход к блокировкам не как у взрослых СУБД, он другой. Тут книга по SQLite на русском , там один раздел про работу блокировок, советую почитать.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996966
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql,
Почему бы тебе организовать очередь например BlockingCollection, из комманд к SQLLite базе? Очередь будет очищаться посредством удаления выполненных комманд и все будет в одном потоке?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39996975
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,

слишком мудрено получится, где-то надо например вставить массив, где-то распихать нескольким по таблицам, связанным ключом. Т.е. разные ф-ции получатся, а некоторые еще и что-то возвращают. Этож какую структуру мне придется изобретать чтоб пропихнуть через коллекцию, а потом ее еще и расшифровывать. А в обратку вернуть данные еще одна коллекция? Тогда как сделать так чтоб данные из нее схватил "нужный" поток? Либо я что-то не понимаю, либо хрень какая-то выходит.

Да и зачем плодить сущности, разве недостаточно класса, содержащего ф-ции, доступ к которым в единый момент времени имеет только один поток.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39997142
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql
Да задача то примитивная - писать в базу sqlite. Мне показалось проще понаставить локов, чем отлавливать исключения "база занята" и делать повторные попытки...


Понаставить локов -- самое кривое решение, из всех, что вы могли выбрать.
SQLite не предназначена для использования в многопользовательской среде изначально, т.е. вы пытаетесь применить инструмент в задачах, для которых нужно применять другой инструмент.

Если прям очень хочется, организуйте очередь.
Но лучше возьмите более подходящую БД для своих задач, зачем извращаться?

iskatelsql
Ну и так, для общего развития - мож еще зачем пригодится когда-нибудь..


Покрытие локами вам не пригодиться. По крайне мере в любом более менее серьёзном проекте подобные решения не одобрят, так как адские костыли. При желании конечно можно и лоб расшибить. Но зачем?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39997146
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Понаставить локов -- самое кривое решение, из всех, что вы могли выбрать.
SQLite не предназначена для использования в многопользовательской среде изначально, т.е. вы пытаетесь применить инструмент в задачах, для которых нужно применять другой инструмент.

Я подозреваю у него не многопользовательская среда, а работа с БД из разных потоков. Тут и локов не надо, т.к. это все разруливается внутри SQLite. По сути тоже самое будет, т.к. система блокировок в SQLite примитивна, там одна большая блокировка на всю БД, т.е. по сути тоже самое что ТС изобретает.
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39997859
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
hVostt
Понаставить локов -- самое кривое решение, из всех, что вы могли выбрать.
SQLite не предназначена для использования в многопользовательской среде изначально, т.е. вы пытаетесь применить инструмент в задачах, для которых нужно применять другой инструмент.

Я подозреваю у него не многопользовательская среда, а работа с БД из разных потоков. Тут и локов не надо, т.к. это все разруливается внутри SQLite. По сути тоже самое будет, т.к. система блокировок в SQLite примитивна, там одна большая блокировка на всю БД, т.е. по сути тоже самое что ТС изобретает.


Ну это проблема так называемого execution path, алгоритмов. Большинство проблем связаны с невозможностью описать процесс на словах. Обычным русским языком, нет постановки задачи, нет проработки, нет чётко сформулированных ожиданий.

Т.е. оно вот так. Вот что-то в базу пишу, тут вот присваиваю, чёт читаю.. Оппа -- ошибка. Ошибка вроде как говорит, чувак, ты вообще всё непраивльно делаешь? Чего ты творишь вообще?

Но программер неумолим.. Заткнись глупый компьютер, щас я всё локами покрою, посомтрю как ты запоёшь :)
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39998005
iskatelsql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Ну это проблема так называемого execution path, алгоритмов.
Да, именно так. есть неизвестная шляпа, которую изучаем. Вроде как алгоритм построен - вычитываем нужно до старта потоков, из потоков пишем обновления, ног могут быть нюансы...

тесты показывают что и без локов есть 30 сек на запись, наверное обойдусь без них.

Вот только почему все так против этих локов? их добавили чтоб на форумах смеяться? Механизм как механизм. (правильно я понимаю, что таск на локе отдает поток другим страждушим?)

ЗЫ. если я про семафоры скажу, меня тут забанят?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #39998030
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql
...А локи - локи вроде ничего так подходят, ну стоит поток (Тем более что это не совсем поток, а Task и на локах должен по идее освободить поток для других задач.)

Task + lock - интересный микс
выж про async/await код?
можете свой первый пример допилить и показать где там Task и где lock?
...
Рейтинг: 0 / 0
Как "залочить" весь класс?
    #40000602
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iskatelsql
Вот только почему все так против этих локов? их добавили чтоб на форумах смеяться? Механизм как механизм. (правильно я понимаю, что таск на локе отдает поток другим страждушим?)


Против использования микроскопа в качестве молотка, но не против самого микроскопа.

iskatelsql
ЗЫ. если я про семафоры скажу, меня тут забанят?


Смотря что скажете :)
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как "залочить" весь класс?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]