Пропустить строку в таблице??

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
Привет, народ)
Столкнулся с нетривиальной задачей -
Нужно, при взятии строки из таблицы, чтобы 1й поток взял бы 1ую строку. 2ой поток - 2ую и тд
lock и mutex пробовал - не дают нужного эффекта
В итоге, составил такой код, который приблизил меня к результату. Возможно тут ошибка:
C#:
//Проверяем статус строки - актуально или в работе
//Тут общий цикл работы с таблицей for(){

                    for(rowNum=0;rowNum<=GoodsInCab.RowCount;rowNum++){
                       
                        string Status = GoodsInCab.GetCell("F", h);
                        project.SendInfoToLog("Идем по строке № - " + rowNum);
                        if(Status=="Актуально"){
                            System.Threading.Thread.Sleep(rnd.Next(3000, 4500));
                            project.SendInfoToLog("Ставим статус - 'Работаем' текущему объявлению", true);
                            GoodsInCab.SetCell("F", h, "Работаем");
                            System.Threading.Thread.Sleep(rnd.Next(3000, 4500));
                            project.SendInfoToLog("Текущий номер строки - " + rowNum, true);
                            rowNum=h;
                            break;
                        }
                    }
//Здесь строки кода, которые работают с другими столбцами - номер строки лежит в h
}

Замысел такой - 1й поток берет 1ую строку в работу, ставит в ячейку F статус "Работаем", 2й поток "видит" этот статус, пропускает эту строку, берет следующую, у которой статус - "Актуально" и т.д. со всеми потоками.
По факту получается, что все потоки работают только с первой строкой. Как решить эту задачу? Можете помочь?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
дает. постоянно с ним работаю. код с локом в студию, щас найдем косяки :ca:
пожалуйста:
C#:
for(int h=0;h<=GoodsInCab.RowCount;h++){
                    
                    //Остановка, когда прошли все строки в таблице
                    if(h==GoodsInCab.RowCount){                       
                        throw new Exception("Обошли все объявления в таблице с которыми нужно было работать. Работа шаблона остановлена до  наступления времени в расписании");
                    }
                    
                    
                    //mutex.WaitOne();
                    project.SendInfoToLog("Проверяем статус текущего объявления - 'Работаем' или 'Актуально' ?", true);
                    
                    lock(SyncObjects.TableSyncer){
                    
                        //Проверяем статус строки - актуально или в работе
                        for(rowNum=0;rowNum<=GoodsInCab.RowCount;rowNum++){
                            
                            string Status = GoodsInCab.GetCell("F", h);
                            project.SendInfoToLog("Идем по строке № - " + rowNum);
                            if(Status=="Актуально"){
                                System.Threading.Thread.Sleep(rnd.Next(3000, 4500));
                                project.SendInfoToLog("Ставим статус - 'Работаем' текущему объявлению", true);
                                GoodsInCab.SetCell("F", h, "Работаем");
                                System.Threading.Thread.Sleep(rnd.Next(3000, 4500));
                                project.SendInfoToLog("Текущий номер строки - " + rowNum, true);
                                rowNum=h;
                                break;
                            }
                        }
                    
                    }
                
                    project.Variables["AdvLink"].Value = GoodsInCab.GetCell("H",h);
                    project.SendInfoToLog(project.Variables["AdvLink"].Value,true);
                    project.Variables["TimeOn"].Value = GoodsInCab.GetCell("I",h);
                    project.SendInfoToLog(project.Variables["TimeOn"].Value,true);                       
                    project.Variables["TimeOff"].Value = GoodsInCab.GetCell("J",h);
                    project.SendInfoToLog("Время выключения - " + project.Variables["TimeOff"].Value,true);
                    //instance.WaitForUserAction(50);
                    project.Variables["WhatToDo"].Value = GoodsInCab.GetCell("K",h);
                    project.SendInfoToLog(project.Variables["WhatToDo"].Value,true);
                    string SetOn = GoodsInCab.GetCell("L",h);
                    project.SendInfoToLog(SetOn,true);
                    project.Variables["SetOff"].Value = GoodsInCab.GetCell("M",h);
                    project.SendInfoToLog(project.Variables["SetOff"].Value,true);
                    string PriceForFirstPlace = GoodsInCab.GetCell("N",h);
                    project.SendInfoToLog(PriceForFirstPlace,true);
                    string PriceForFirstPage = GoodsInCab.GetCell("O",h);
                    project.SendInfoToLog(PriceForFirstPage,true);
                    project.Variables["Archive"].Value = GoodsInCab.GetCell("P",h);
                    project.SendInfoToLog(project.Variables["Archive"].Value,true);
                    project.Variables["GoodsInSell"].Value = GoodsInCab.GetCell("Q",h);
                    project.SendInfoToLog(project.Variables["GoodsInSell"].Value,true);
                    
                    //mutex.ReleaseMutex();
                        
                    if(String.IsNullOrWhiteSpace(project.Variables["TimeOn"].Value)){
                        project.SendWarningToLog("Не заполнено время выключения для объявления - " + project.Variables["AdvLink"].Value + " пропускаем его",true);
                        
                        //здесь оч много кода, поэтому закрыл for тут
                    }
 

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 021
Благодарностей
1 383
Баллы
113
lock надо вынести за пределы for.
Конструкция такая

C#:
int row = 0;
lock(SyncObjects.TableSyncer){
    for(int i = 0; i < table.RowCount(); i++){
        if(table.GetCell("F", i).Contains("Работаем"))
            continue;
        else{
            row = i;
            break;
        }
    }
}
//далее каждый поток работает со своей строкой таблицы вне лока и вне цикла.
 

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
lock надо вынести за пределы for.
Конструкция такая

C#:
int row = 0;
lock(SyncObjects.TableSyncer){
    for(int i = 0; i < table.RowCount(); i++){
        if(table.GetCell("F", i).Contains("Работаем"))
            continue;
        else{
            row = i;
            break;
        }
    }
}
//далее каждый поток работает со своей строкой таблицы вне лока и вне цикла.
А если в цикл for выполняется огромный цикл, который отвечает за разные настройки? его весь в lock складывать?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113
код выше подсказали.
но и я хочу свои 5 копеек вставить :ca:
1. у тебя стоит конструкция for(int h=0;h<=GoodsInCab.RowCount;h++){
её выбьет по ошибке на последней строке. надо использовать < а не <=
2. у тебя вложенный цикл в основной, вообще не несет логической нагрузки. убери его.
3. при использовании лока, нельзя пользоваться паузами. лок должен быть мгновенным, что бы не вставали другие потоки
 
  • Спасибо
Реакции: djaga

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
3. при использовании лока, нельзя пользоваться паузами. лок должен быть мгновенным, что бы не вставали другие потоки
а вот тут кроет "жопа" № 2 - не успевают записываться значения в таблицу)) так что не все так просто) поэтому поставил паузу в 3 сек., тогда записывается
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113
а вот тут кроет "жопа" № 2 - не успевают записываться значения в таблицу)) так что не все так просто) поэтому поставил паузу в 3 сек., тогда записывается
все успевает. зенка работает со своим кешем в памяти и все изменения все шаблоны видят мгновенно. синхронизация с файлом это отдельный процесс не влияющий на результат работы. главное использовать лок.
 

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
все успевает. зенка работает со своим кешем в памяти и все изменения все шаблоны видят мгновенно. синхронизация с файлом это отдельный процесс не влияющий на результат работы. главное использовать лок.
если бы я не видел это своими глазами, я бы не говорил)

За помощь, спасибо
 

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8
Копался в коде. Докопался, что нормально не отрабатывает эта конструкция:
C#:
int x=0;   
        
        lock(SyncObjects.TableSyncer){
            
            Status = ExportTable.GetCell("F", x);
            project.SendInfoToLog("Status - " + Status,true);
            
            //Проверяем статус строки - акутально или в работе
            for(rowNum=0;rowNum<=ExportTable.RowCount;rowNum++){
                project.SendInfoToLog("rowNum - " + rowNum,true);
                if(!ExportTable.GetCell("G",x).Contains("Работаем")){
                    ExportTable.SetCell("G", x, "Работаем");
                    project.SendInfoToLog("Поставили строке " + rowNum + " статус 'Работаем' ",true);
                    break;
                }
            }
        }
Первой строке статус "Работаем" ставит нормально, дальше все строки просто пробегает, хотя там статуса нет.
В чем может быть вопрос?
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113
Копался в коде. Докопался, что нормально не отрабатывает эта конструкция:
C#:
int x=0;  
       
        lock(SyncObjects.TableSyncer){
           
            Status = ExportTable.GetCell("F", x);
            project.SendInfoToLog("Status - " + Status,true);
           
            //Проверяем статус строки - акутально или в работе
            for(rowNum=0;rowNum<=ExportTable.RowCount;rowNum++){
                project.SendInfoToLog("rowNum - " + rowNum,true);
                if(!ExportTable.GetCell("G",x).Contains("Работаем")){
                    ExportTable.SetCell("G", x, "Работаем");
                    project.SendInfoToLog("Поставили строке " + rowNum + " статус 'Работаем' ",true);
                    break;
                }
            }
        }
Первой строке статус "Работаем" ставит нормально, дальше все строки просто пробегает, хотя там статуса нет.
В чем может быть вопрос?
что за x ? что она делает и для чего ? кажется ты работаешь с разными строками....

75223
 

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8

Nelirr

Пользователь
Регистрация
23.03.2021
Сообщения
86
Благодарностей
7
Баллы
8

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