Обьясните как работает lock(SyncObjects.TableSyncer)

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
На сколько я понял эти локи работают по ИМЕНИ ТАБЛИЦЫ?
Не по адресу расположения таблицы, а именно имени в PM, так?
И применять их надо только если нужен многопоток?
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
На сколько я понял эти локи работают по ИМЕНИ ТАБЛИЦЫ?
Нет, они работают по ссылочному элементу, таблица как раз ссылается на элемент в куче (можешь не вникать в это, не обязательно понимать).
Не по адресу расположения таблицы, а именно имени в PM, так?
Можно поставить любой ссылочный элемент и блокировать им. В некоторых случаях (с этим надо быть осторожным) можно блокировать таблицу обычным названием переменной string
И применять их надо только если нужен многопоток?
Да, если нету многопотока, можешь забыть об этой строке и удалить её нахер
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
Нет, они работают по ссылочному элементу, таблица как раз ссылается на элемент в куче (можешь не вникать в это, не обязательно понимать).
А как лок работает?
1. Например есть 2 шаблона, в каждом есть таблица "table", и таблицы заполняются в проекте (без загрузки из файла), при одновременной работе этих шаблонов, один из шаблонов будет лочить другой пока не выполнится сниппет другого шаба?
2. Пример, тоже самое что в 1, только таблицы имеют разные названия, но они загружаются из одного файла. Будут ли один шаб стопить другой из за лока?
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
Вот у меня проблема.
Есть шаб, в котором таблица загружается из файла (не редактируется)
И есть второй шаб, который работает в многопотоке с локом с этой же таблицей и записывает в ней данные.

Первый шаб все время стопится из-за того, что многопоточный шаб локает эту таблицу.
В обоих шаблонах название таблицы одинаковое.
Мне надо сменить название таблицы в первом шабе или это никак не пофиксить?
 

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
А как лок работает?
1. Например есть 2 шаблона, в каждом есть таблица "table", и таблицы заполняются в проекте (без загрузки из файла), при одновременной работе этих шаблонов, один из шаблонов будет лочить другой пока не выполнится сниппет другого шаба?
2. Пример, тоже самое что в 1, только таблицы имеют разные названия, но они загружаются из одного файла. Будут ли один шаб стопить другой из за лока?
1) Если это разные шаблоны, которые запущены одновременно, то они друг на друга не влияют и ничего блокировать не нужно вне зависимости от названия таблицы. На 100% не уверен в этом, так как внутреннюю реализацию зенки знают только сами разрабы зенки. Я лично предполагаю, что там они идут независимо.
2) Стопить не будут, но при загрузке из файла может вылезти ошибка доступа. Плюс при сохранении изменений они могут конфликтовать
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
Помогите, пожалуйста,
Вот у меня проблема.
Есть шаб, в котором таблица загружается из файла (не редактируется)
И есть второй шаб, который работает в многопотоке с локом с этой же таблицей и записывает в ней данные(таблица из файла, с сохранением)

Первый шаб все время стопится из-за того, что многопоточный шаб локает эту таблицу.
Названия менял таблиц и все равно стопит шаблон.
Как вариант можно конечно таблицу перекопировать в другую и с ней работать, но это так себе вариант.
Может есть более оптимальный вариант?

Самое тупое, это то что шаб стопится, когда эта таблица НЕ ИСПОЛЬЗУЕТСЯ.
Пожалуйста, объясните как нормально эту ситуацию пофиксить?
 

freeman

Client
Регистрация
31.07.2010
Сообщения
130
Благодарностей
138
Баллы
43
Вероятно, ты обернул в лок не тот участок кода. Лочить надо только непосредственно сами операции над таблицами, которые должны отрабатывать мгновенно.
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
Вероятно, ты обернул в лок не тот участок кода. Лочить надо только непосредственно сами операции над таблицами, которые должны отрабатывать мгновенно.
Я локнул в одном шабе кусок кода, в котором большой цикл, который обрабатывается ~30сек. Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит.
Может я чего-то не знаю или упустил.
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28

justhelen

Client
Регистрация
18.11.2009
Сообщения
267
Благодарностей
134
Баллы
43
Я локнул в одном шабе кусок кода, в котором большой цикл, который обрабатывается ~30сек. Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит.
Может я чего-то не знаю или упустил.
Тебе не нужно лочить весь цикл. Локни только ту строку (строки), где ты меняешь данные в таблице. Прямо внутри цикла оберни такие строки в лок.
 
  • Спасибо
Реакции: Art4D

justhelen

Client
Регистрация
18.11.2009
Сообщения
267
Благодарностей
134
Баллы
43
Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит
Это очень странно. lock не может залочить что-то на много разных шабов. Лочится кусок кода в пределах одного шаба, тогда много потоков одного шаба обрабатывают локнутый кусок кода по очереди. Я думаю, тут что-то другое. Может быть, другой шаб висит, потому что не может получить доступ к файлу, к которому привязана таблица, потому что ему что-то из этой таблицы надо (а ей надо из файла), а в файл долго идёт запись в этот момент. Так может быть если например очень много строк в файле, тогда следующая может долго добавляться. Ну, что-то такое. Т.е. я не знаю, что, я шабов не видела, но как-то так. Ну не может быть лока на 2 разных шаба.

Если дело в огромном файле, то можно сделать вот как.

1. Создаём папку.
2. шаб1, как я поняла, за время своего выполнения пишет много строк в таблицу? (ты сказал, там большой цикл). Но при этом шаб1 не использует сам эти строки. Так вот, шаб1 вообще отказывается от таблицы, в начале генерирует рандомную последовательность букв и цифр, запоминает (получается что-то типа "fgT7yh9ufg"). шаб1 сохраняет строки в файл с именем "fgT7yh9ufg.txt" в папке, которую мы создали. В итоге получится папка, в которой лежит много таких файлов и в каждом, например 1000 строк (это если в длинном цикле было 1000 итераций).
3. В шабе2 (который только использует строки) есть таблица без привязки к файлу. В начале выполнения шаба2 в C# сниппете выбираем рандомный файл из папки из шага 2, читаем из него строки, записываем в эту таблицу.

Но это вот если у тебя ни один из шабов не удаляет эти строки. Ты ничего не написал про удаление, поэтому предполагаю, что его нет. И ещё, если в большом цикле 10 итераций и поэтому получится много файлов с 10 строками - это тоже плохо (будет очень много мелких файлов в одной папке, тогда доступ к ним тоже очень долгий + фрагментация диска) Про это тоже ничего не сказано, поэтому предполагаю, что в цикле много итераций (не просто же так он длится 30 секунд).
 
Последнее редактирование:
  • Спасибо
Реакции: Art4D

Valiksim

Client
Регистрация
14.04.2012
Сообщения
1 344
Благодарностей
298
Баллы
83
Тебе не нужно лочить весь цикл. Локни только ту строку (строки), где ты меняешь данные в таблице. Прямо внутри цикла оберни такие строки в лок.
Тут пример нужен, иначе непонятно
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
~30сек он длится, потому что в зенно таблицы работают медленно очень. Пример:
Сниппет, который длится 30 сек:
PHP:
var sourceTable = project.Tables["tabl1"];
var savetable = project.Tables["W"];
var a = true;
lock(SyncObjects.TableSyncer)
{
    for(int i=0; i < sourceTable.RowCount; i++)
    {
        string name = sourceTable.GetCell("A", i);
        string price1 = sourceTable.GetCell("B", i);
        for(int j=0; j < savetable.RowCount; j++)
    {
        string cname = savetable.GetCell("A", j); //читаем ячейку
        if (name==cname)
        {
            string tprice1 = savetable.GetCell("D", j); //читаем ячейку
            double tprice = Convert.ToDouble(tprice1);
            savetable.SetCell("B", j, price1); //сохраняем данные
            double cprice = Convert.ToDouble(price1);
            double k=Math.Round(0.95*tprice*10/cprice);
            string c = Convert.ToString(k);  
            savetable.SetCell("C", j, c); //сохраняем данные
            a = false;
            break;
        }
        a=true;
    }
    if (a==true)
    savetable.AddRow(new [] { name, price1, "1", "1", "1" }); //сохраняем данные
    }
}
А вот тот же самый сниппет, только реализован через списки, работает 5 сек:
PHP:
for (int i=0; i<project.Tables["tabl1"].RowCount; i++)
{
    project.Lists["name"].Add(project.Tables["tabl1"].GetCell(0,i));
    project.Lists["price"].Add(project.Tables["tabl1"].GetCell(1,i));
}
for (int i=0; i<project.Tables["W"].RowCount; i++)
{
    project.Lists["namec"].Add(project.Tables["W"].GetCell(0,i));
    project.Lists["pricec"].Add(project.Tables["W"].GetCell(1,i));
    project.Lists["koefc"].Add(project.Tables["W"].GetCell(2,i));
    project.Lists["tprice"].Add(project.Tables["W"].GetCell(3,i));
}

var firstList = project.Lists["name"];
var secondList = project.Lists["namec"];
var trList = project.Lists["price"];
var fourList = project.Lists["pricec"];
var fiveList = project.Lists["koefc"];
var sixList = project.Lists["tprice"];
var a = true;

    for(int i=0; i < firstList.Count; i++)
    {
        var str1 = firstList[i];
        for(int j=secondList.Count-1; j >= 0; j--)
        {
            var str2 = secondList[j];
            if (str1==str2)
            {
                fourList.RemoveAt(j);
                fourList.Insert(j, trList[i]);
                a = false;
                break;
            }
            a=true;
    }
    if (a==true)
project.Tables["W"].AddRow(new [] { firstList[i], trList[i], "1", "1", "1" });
    }
  
    for(int i=0; i < sixList.Count; i++)
    {
    fiveList.RemoveAt(i);
        double tprice = double.Parse(sixList[i]);
        double pricec = double.Parse(fourList[i]);
    double k=Math.Round(0.95*tprice*10/pricec);
    string c = Convert.ToString(k);      
    fiveList.Insert(i, c);
    }
И далее три списка кладутся в столбцы таблицы.
 
  • Спасибо
Реакции: Valiksim

VladZen

Administrator
Команда форума
Регистрация
05.11.2014
Сообщения
22 453
Благодарностей
5 912
Баллы
113
~30сек он длится, потому что в зенно таблицы работают медленно очень. Пример:
Сниппет, который длится 30 сек:
PHP:
var sourceTable = project.Tables["tabl1"];
var savetable = project.Tables["W"];
var a = true;
lock(SyncObjects.TableSyncer)
{
    for(int i=0; i < sourceTable.RowCount; i++)
    {
        string name = sourceTable.GetCell("A", i);
        string price1 = sourceTable.GetCell("B", i);
        for(int j=0; j < savetable.RowCount; j++)
    {
        string cname = savetable.GetCell("A", j); //читаем ячейку
        if (name==cname)
        {
            string tprice1 = savetable.GetCell("D", j); //читаем ячейку
            double tprice = Convert.ToDouble(tprice1);
            savetable.SetCell("B", j, price1); //сохраняем данные
            double cprice = Convert.ToDouble(price1);
            double k=Math.Round(0.95*tprice*10/cprice);
            string c = Convert.ToString(k); 
            savetable.SetCell("C", j, c); //сохраняем данные
            a = false;
            break;
        }
        a=true;
    }
    if (a==true)
    savetable.AddRow(new [] { name, price1, "1", "1", "1" }); //сохраняем данные
    }
}
А вот тот же самый сниппет, только реализован через списки, работает 5 сек:
PHP:
for (int i=0; i<project.Tables["tabl1"].RowCount; i++)
{
    project.Lists["name"].Add(project.Tables["tabl1"].GetCell(0,i));
    project.Lists["price"].Add(project.Tables["tabl1"].GetCell(1,i));
}
for (int i=0; i<project.Tables["W"].RowCount; i++)
{
    project.Lists["namec"].Add(project.Tables["W"].GetCell(0,i));
    project.Lists["pricec"].Add(project.Tables["W"].GetCell(1,i));
    project.Lists["koefc"].Add(project.Tables["W"].GetCell(2,i));
    project.Lists["tprice"].Add(project.Tables["W"].GetCell(3,i));
}

var firstList = project.Lists["name"];
var secondList = project.Lists["namec"];
var trList = project.Lists["price"];
var fourList = project.Lists["pricec"];
var fiveList = project.Lists["koefc"];
var sixList = project.Lists["tprice"];
var a = true;

    for(int i=0; i < firstList.Count; i++)
    {
        var str1 = firstList[i];
        for(int j=secondList.Count-1; j >= 0; j--)
        {
            var str2 = secondList[j];
            if (str1==str2)
            {
                fourList.RemoveAt(j);
                fourList.Insert(j, trList[i]);
                a = false;
                break;
            }
            a=true;
    }
    if (a==true)
project.Tables["W"].AddRow(new [] { firstList[i], trList[i], "1", "1", "1" });
    }
 
    for(int i=0; i < sixList.Count; i++)
    {
    fiveList.RemoveAt(i);
        double tprice = double.Parse(sixList[i]);
        double pricec = double.Parse(fourList[i]);
    double k=Math.Round(0.95*tprice*10/pricec);
    string c = Convert.ToString(k);     
    fiveList.Insert(i, c);
    }
И далее три списка кладутся в столбцы таблицы.
У вас сниппет для таблиц использует лок, а сниппет для списков нет.
Попробуйте поставить DateTime.Now перед локом, сразу после лока, в конце сниппета, чтобы понять сколько времени тратится на вход в лок.
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
У вас сниппет для таблиц использует лок, а сниппет для списков нет.
Попробуйте поставить DateTime.Now перед локом, сразу после лока, в конце сниппета, чтобы понять сколько времени тратится на вход в лок.
так для списков лок и не нужен, а экшен "Добавить список в таблицу" имеет встроенный лок насколько я понял.
В зенно таблицы работают просто медленно, GetCell и SetCell, я вот сейчас на списках сделал и 5сек меня устраивает, это не критично.
 

VladZen

Administrator
Команда форума
Регистрация
05.11.2014
Сообщения
22 453
Благодарностей
5 912
Баллы
113
так для списков лок и не нужен, а экшен "Добавить список в таблицу" имеет встроенный лок насколько я понял.
В зенно таблицы работают просто медленно, GetCell и SetCell, я вот сейчас на списках сделал и 5сек меня устраивает, это не критично.
Просто вы сравниваете, сниппеты для списка и для таблицы, и говорите, что время выполнения для списка гораздо быстрее.
 

Art4D

Client
Регистрация
22.08.2014
Сообщения
276
Благодарностей
48
Баллы
28
Просто вы сравниваете, сниппеты для списка и для таблицы, и говорите, что время выполнения для списка гораздо быстрее.
Нет не так, Мне нужно обработать таблицу, и первый сниппет работает с таблицей, на это уходит ~30сек.
Поэтому мне приходится таблицу разбивать на списки, и обрабатывать списки, и потом обработанные списки класть в таблицу. И на это уходит ~5сек.
Т.е. результат у этих двух действий будет одинаковый. Так что таблицы работают в разы медленнее списков.
Т.е. в конечном результате в этих двух случаях, проект заканчивает работу сохранением обработанной таблицы в файл.
 
Последнее редактирование:

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)