Нет, они работают по ссылочному элементу, таблица как раз ссылается на элемент в куче (можешь не вникать в это, не обязательно понимать).На сколько я понял эти локи работают по ИМЕНИ ТАБЛИЦЫ?
Можно поставить любой ссылочный элемент и блокировать им. В некоторых случаях (с этим надо быть осторожным) можно блокировать таблицу обычным названием переменной stringНе по адресу расположения таблицы, а именно имени в PM, так?
Да, если нету многопотока, можешь забыть об этой строке и удалить её нахерИ применять их надо только если нужен многопоток?
А как лок работает?Нет, они работают по ссылочному элементу, таблица как раз ссылается на элемент в куче (можешь не вникать в это, не обязательно понимать).
1) Если это разные шаблоны, которые запущены одновременно, то они друг на друга не влияют и ничего блокировать не нужно вне зависимости от названия таблицы. На 100% не уверен в этом, так как внутреннюю реализацию зенки знают только сами разрабы зенки. Я лично предполагаю, что там они идут независимо.А как лок работает?
1. Например есть 2 шаблона, в каждом есть таблица "table", и таблицы заполняются в проекте (без загрузки из файла), при одновременной работе этих шаблонов, один из шаблонов будет лочить другой пока не выполнится сниппет другого шаба?
2. Пример, тоже самое что в 1, только таблицы имеют разные названия, но они загружаются из одного файла. Будут ли один шаб стопить другой из за лока?
Названия менял таблиц и все равно стопит шаблон.Вот у меня проблема.
Есть шаб, в котором таблица загружается из файла (не редактируется)
И есть второй шаб, который работает в многопотоке с локом с этой же таблицей и записывает в ней данные(таблица из файла, с сохранением)
Первый шаб все время стопится из-за того, что многопоточный шаб локает эту таблицу.
Я локнул в одном шабе кусок кода, в котором большой цикл, который обрабатывается ~30сек. Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит.Вероятно, ты обернул в лок не тот участок кода. Лочить надо только непосредственно сами операции над таблицами, которые должны отрабатывать мгновенно.
Тебе не нужно лочить весь цикл. Локни только ту строку (строки), где ты меняешь данные в таблице. Прямо внутри цикла оберни такие строки в лок.Я локнул в одном шабе кусок кода, в котором большой цикл, который обрабатывается ~30сек. Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит.
Может я чего-то не знаю или упустил.
Это очень странно. lock не может залочить что-то на много разных шабов. Лочится кусок кода в пределах одного шаба, тогда много потоков одного шаба обрабатывают локнутый кусок кода по очереди. Я думаю, тут что-то другое. Может быть, другой шаб висит, потому что не может получить доступ к файлу, к которому привязана таблица, потому что ему что-то из этой таблицы надо (а ей надо из файла), а в файл долго идёт запись в этот момент. Так может быть если например очень много строк в файле, тогда следующая может долго добавляться. Ну, что-то такое. Т.е. я не знаю, что, я шабов не видела, но как-то так. Ну не может быть лока на 2 разных шаба.Как раз на это время лочится другой шаб, в котором есть эта таблица, НО она в нем без сохранения и НЕ используется тогда, когда шаб лочит
Тут пример нужен, иначе непонятноТебе не нужно лочить весь цикл. Локни только ту строку (строки), где ты меняешь данные в таблице. Прямо внутри цикла оберни такие строки в лок.
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" }); //сохраняем данные
}
}
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);
}
У вас сниппет для таблиц использует лок, а сниппет для списков нет.~30сек он длится, потому что в зенно таблицы работают медленно очень. Пример:
Сниппет, который длится 30 сек:
А вот тот же самый сниппет, только реализован через списки, работает 5 сек: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" }); //сохраняем данные } }
И далее три списка кладутся в столбцы таблицы.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 перед локом, сразу после лока, в конце сниппета, чтобы понять сколько времени тратится на вход в лок.
Просто вы сравниваете, сниппеты для списка и для таблицы, и говорите, что время выполнения для списка гораздо быстрее.так для списков лок и не нужен, а экшен "Добавить список в таблицу" имеет встроенный лок насколько я понял.
В зенно таблицы работают просто медленно, GetCell и SetCell, я вот сейчас на списках сделал и 5сек меня устраивает, это не критично.
Нет не так, Мне нужно обработать таблицу, и первый сниппет работает с таблицей, на это уходит ~30сек.Просто вы сравниваете, сниппеты для списка и для таблицы, и говорите, что время выполнения для списка гораздо быстрее.