| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Удаление строки и потоки |
| Автор: ZBugz 12.4.2010, 14:35 |
| Всем привет. Помогите Смысл вот в чем. Есть ListView, в нем задания, выделяю что надо, запускаю, по окончании могу удалить, а могу и руками удалить выделенную строку. При смещении элементов, меняеться ItemIndex. Ну в итоге в потоке они друг на друга лезут и все зависает. Мне надо что бы в потоке во всех Synchronize() вывлдилась инфа по конкретной строке, поэтому я привязался к строке, но потом понял что при удалении, даже если пройтись по списку и переназначить Index то возможно где то он измениться все равно. Говорят что можно написать используя Lv.Data. Я вообще не понял как это делать... Помогите Пример прилогаю, мне бы с пояснениями и желательно максимально сохранить струтуру кода. |
| Автор: ZBugz 12.4.2010, 16:08 | ||||||
Так, это я сделаю
Значит так, выделяю задания, они ухоодят в поток, выполняються, от каждого задания в его строчку пишу данные, типа сколько процентов выполнено. В момет выполнения я заходл удалить строку, удалил. Последующие строки сдивнулись, отображение информации соответственно должно тоже сдвинуться, я это сделал. А вот если поток завершился, к примеру 2-е задание раньше чем 1-е и т.д. То оно по окончании удаляеться, но так как задание (строка), к примеру 3, тоже завершилось и тоже встало в очередь на удаление, а ItemIndex уже поменялся, то в итоге задание отписывает что оно завершенно в тот itemIndex, которого уже нету. Ну и получаем ошибку.
Да тут впринципе не о нем речь. Добавлено через 1 минуту и 5 секунд Проблема в том, что информацию я вывожу от номера строки, по другому просто не умею :( |
| Автор: Akella 12.4.2010, 20:49 | ||||||
Ты выполняешь это всё в потоке? Или ты не понимаешь, http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=delphi+%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B8? Или я не могу догнать, в чём у тебя проблема. Многабукаф - мало толку. Кхм... тогда о чём? Добавлено через 1 минуту и 6 секунд
Ага, значит речь именно о потоках Добавлено через 2 минуты и 34 секунды
Да, в Data можно записать какой-нибудь уникальный код, когда ты добавляешь очередную строку. |
| Автор: Akella 12.4.2010, 21:30 |
![]() Обрати внимание на нумерацию справа. Я создал по порядку все строки в списке. Потом удалили несколько нечётных. Затем скопировал в мемо всё. При чём номера строк в мемо брал из Data. Проект прикрепил. |
| Автор: Akella 12.4.2010, 21:31 |
| Проект был создан на Delphi 2007 |
| Автор: ZBugz 13.4.2010, 09:25 | ||
Я так делал. Та то работает. Мне бы как в моем поекте |
| Автор: Akella 13.4.2010, 10:43 | ||
тогда поясни, к чему был этот вопрос
|
| Автор: ZBugz 13.4.2010, 13:09 |
| Я имел ввиду что бы прям в дату весь поток запихнуть (потом, когда надо удалить поток\строку) и выводить информацию от тех параметров которые я в поток передал не привязываясь к строке. |
| Автор: Akella 13.4.2010, 15:34 |
Ты хоть посмотрел какой тип имеет Data? И я не представляю, как в переменную можно запихнуть поток?? (если бы Data была переменной) |
| Автор: Mikel 13.4.2010, 19:56 |
| В Data можно запихнуть хоть паровоз |
| Автор: ZBugz 14.4.2010, 07:38 | ||
Mikel прав. Запихиваеться легко, я пробывал Но суть не в этом, меня это не устраивает по другим причинам. Я сегодня отпишу, как только проверю одну весчь от Akella |
| Автор: Akella 14.4.2010, 09:01 |
| Data - это указатель, потому поток туда не запихнёшь ;) |
| Автор: ZBugz 14.4.2010, 14:02 | ||||
Блин, я в шоке Короче, все сделал типа так:
Гиде CT это массив CT: array [1..2000] of TThread; и idx это номер потока Так вот, 0 и 1 строка нормально отображаеться, а все что выше, почему то сьежает ниже через строку... Короче, берем 2-е задание, нажимаю выполнить, до CT[idx].Start и в потоке в Create N.Index=2 (N: TListItem), в Execute попадает как N.Index=3. И это только тогда, когда я добавил задания в чистый ListView, если загрузить с заданиями, то ниче не двигаеться. Шё це такэ ? |
| Автор: Akella 14.4.2010, 16:06 | ||
и всё равно засовываешь TThread в Pointer Добавлено через 49 секунд Это называется "Впихнём невпихуемое", да? Добавлено через 1 минуту и 31 секунду Продолжай в том же духе. За упорство Ктулху тебя вознаградит. |
| Автор: ZBugz 15.4.2010, 07:25 | ||
Почему так нельзя ? Тока вот глючок что если выбрать задание со 2-й строки, перепрыгивает на 1 index больше.... Причем в greate приходит 2, а в execute уже 3 |
| Автор: Akella 15.4.2010, 11:13 | ||
ну тогда не знаю |
| Автор: kami 15.4.2010, 22:48 |
Это лишнее. Я про CT[idx]. Не стоит один экземпляр класса/структуры etc.. учитывать в нескольких местах, это может привести к неявностям при их удалении. лучше сразу "запихивать" в Items[i].Data и работать только там, благо TreeView ListView это более чем позволяет. Главное - в OnDeletion избавиться от "впихнутого" в нод экземпляра класса. Если ко всему прочему работать не с индексами элементов в ListView, а хранить в каждом потоке, соответствующем элементу списка, только ссылку на него (при этом индекс элемента при необходимости получать динамически - перебором, к примеру), то отпадает необходимость и в удалении "от конца к началу", это становится непринципиальным. Почему? Это достаточно стандартная практика, и не обязательно для потоков. Я и сейчас нахожу очень удобным "впихивать" экземпляры обслуживающих классов в Socket.Data, Node.Data и т.п. При этом постоянно пользуюсь FastMM и никаких мемликов не наблюдаю (конечно, после ликвидации корявостей из-за невнимательности). |
| Автор: Akella 16.4.2010, 00:16 |
| ну так мы просто присваиваем ссылку на адрес памяти, а не сам поток или объект, так? |
| Автор: ZBugz 16.4.2010, 08:02 | ||||||||
Ага, именно так. Добавлено через 8 минут и 28 секунд
Как бы сказать, понял, но на половину... Можно для тормозов пояснения ?
А вот как тогда вообще от индексов отвязаться ? Впринципе сейчас, при создании потока я передаю Lv.Items[j] Там, в поток.create я присваиваю эту дату переменной N: TListItem и в во всех Синхронайзах я уже использую вывод информации так: N.SubItems[3]:=A и т.д. Т.е. от строки я отвязялся. По завершению, я подаю в главную фому сообщение с номером потока, поток прибиваю, далее читаю настроку и грохую строку. Тем самым убиваю три зайца: Поток 100% завершен, строка грохаеться только после 100% завершения потока и к строкам я не привязан вообще. Единственно что в OnDeletion я ниче не делаю, потому что даже не знаюнадо ли мне в этом случае что то делать. To Akella: А можно ли мне вообще отвязаться от моего массива CT ? И как ?
? |
| Автор: Akella 16.4.2010, 08:54 |
Можно, отказывайся Добавлено через 41 секунду Я, честно, говоря, не знаю, что вообще тебе нужно. Ты ходишь вокруг да около. То тебе нужен массив потоков, то теперь не нужен. |
| Автор: kami 16.4.2010, 12:45 | ||||||||||||||
Нужно отказаться.
В OnDeletion пишем:
Передавай не номер потока в массиве, а указатель на соответствующий ему ListItem. Примечание: далее "я" читать как имхо, и не подразумевать под этим "выпячивание и битие пяткой в грудь". Примерно так (ну, это по моему разумению, я делаю так постоянно): В потоке при необходимости завершения (поток должен знать кроме "своего" ListItem (я обозвал его ParentListItem) еще и хендл окна в основном потоке):
В основном потоке:
Добавлено через 7 минут и 15 секунд
Ну так... любой экземпляр созданного класса (for example - myForm:TForm)- это тоже всего лишь указатель на его поля и методы... |
| Автор: ZBugz 19.4.2010, 09:27 |
| Ага, ладно, попробую отпишусь |