0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
||||||
1 | ||||||
Правильно завершить поток07.03.2016, 12:08. Показов 8683. Ответов 20
Метки нет (Все метки)
Прошу помощи людей, хорошо разбирающихся в многопоточности. Из-за зависания формы приложения во время долгого выполнения (не отвечают никакие элементы управления) пришёл к воплощению многопоточности в дело. Но если делегаты и потоки удалось освоить, то правильно завершить эти потоки никак не удаётся. К сожалению во всей литературе и на форумах не нашёл ответа на этот вопрос, везде речь о создании потока, а не о завершении во время его выполнения. Привожу сильно упрощённый вариант, где в качестве комментарий заключены различные попытки завершения потока. Одна кнопка запускает поток, другая его должна завершать. Вот как это воплотить?
0
|
07.03.2016, 12:08 | |
Ответы с готовыми решениями:
20
Visual Studio 2013 - Как правильно завершить проект и создать install со своим значком Правильно завершить поток Как правильно завершить поток Как правильно завершить поток FileStream |
2 / 2 / 2
Регистрация: 22.04.2014
Сообщений: 18
|
|
07.03.2016, 14:09 | 3 |
Создать переменную, кнопкой стоп присваивать значение, в потоке в цикле проверять переменную, при значении присвоеном кнопкой стоп, выходить из процесса
0
|
07.03.2016, 14:11 | 4 |
dymitri, всё просто.
Есть некий булевый флаг. Флаг установлен в одно положение при старте потока. Устанавливается в другое положение при необходимости завершения потока. В функции. выполняющейся в потоке, идёт периодическая проверка этого флага. Если флаг перешёл в состояние "остановить поток", производится возврат из функции потока. Всё. Ещё у Task из .Net >= 4.0 есть возможность использования CancellationToken.
1
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
07.03.2016, 22:15 [ТС] | 5 |
foxkid, В цикле потока невозможно завершить этот поток, т.к. объявлен и создан он в другой процедуре. Выход же из процедуры не завершает поток! Поэтому и просил совета у ЗНАЮЩИХ эту тему.
Rius, спасибо. Очень интересно было бы увидеть хоть какой-то пример. Если "всё просто", то очень прошу вас подсказать, как бы это осуществить в данном выше упрощённом коде, а я уже додумаю в реальном приложении.
0
|
07.03.2016, 23:12 | 6 |
dymitri, так всё же в справке есть, её для того и пишут.
https://msdn.microsoft.com/ru-... 10%29.aspx
0
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
08.03.2016, 09:10 [ТС] | 7 |
Rius, написанную справку смотрел, но практически ничего не понял, т.к. описание примера на английском. А совета я просил именно по конкретному примеру, а не абстрактно о всём классе. Ссылки на справки могу давать не хуже вас.
GSXL, у меня та же проблема. Даже после закрытия приложения, процесс висит. Наслышан вообще о проблеме правильной выгрузки приложения вместе со всеми процессами. И соответственно, как в приведённом примере правильно закрыть приложение, что бы процесс тоже завершался?
0
|
08.03.2016, 09:50 | 8 | ||||||||||
dymitri, Выжпрограммист, не? С таким подходом далеко не уедете.
1
|
144 / 132 / 34
Регистрация: 28.02.2014
Сообщений: 159
|
||||||
08.03.2016, 11:05 | 9 | |||||
Можно сделать так как сказал Rius:
1
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
08.03.2016, 16:43 [ТС] | 10 |
vova2112, Спасибо огромное! Пока всё работает (кроме варианта закрытия программы во время выполнения процесса). Сейчас займусь вниканием в код (теорию)
Rius, "Выжпрограммист" - чётко!!! Вы правы, я не программист по образованию, занимаюсь смежной темой, но очень часто приходится сталкиваться и с этим. Практически нет возможности полностью изучить VB, т.к. буквально во всей литературе, по которой я обучался VB, вообще отсутствуют темы о Процессах, только в одной вскользь освещена Многозадачность на уровне "чайника". Мне же более знакомы языки (Ассемблер) под очень старое железо, которое теперь можно увидеть лишь в музеях ЭВМ 70-80-х годов. Добавлено через 2 часа 28 минут vova2112, извиняюсь, это я на радостях поспешил поставить точку, не проверив ваш код . Вы несколько ввели меня в заблуждение словами "Можно сделать так как сказал Rius". Хотя на самом деле лишь вставили переменную, о которой говорил не Rius, а foxkid. Такой вариант я уже давно проходил, он не подходит по причине не остановленного процесса после закрытия программы (выше уже писал). Вот если бы можно было в примере увидеть работу с использованием CancellationToken, о котором говорил Rius, но так и не привёл хоть сколько-то актуального кода... Хотя может если будет время попробую разобраться с его приведённым кодом. Но мои Визуал Студио ругаются на одну строку "InitializeComponent()", говорят, что бы заменил...
0
|
08.03.2016, 17:08 | 11 |
dymitri, и я и foxkid, посмотрите на время поста. Но это не важно, это метод известный, дубовый и работающий повсюду.
CancellationToken это из .Net 4.0. Которым есть смысл пользоваться, если Вы не привязаны к младшим версиям .Net. Код я привёл рабочий и актуальный. Только преобразованный из C#. InitializeComponent можно вычеркнуть, в VB она через какие-то костыли вызывается иначе, не из конструктора. Добавлено через 18 минут Он подходит, если поставить булевый флаг при закрытии формы и дождаться завершения потока.
1
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
08.03.2016, 17:32 [ТС] | 12 |
Rius, Ну да вы оба говорили о флаге, я ещё до этого сам пробовал с переменными для закрытия делать. Но значит просто проблема с закрытием формы. Просто именно вы как-то конкретно стали говорить о CancellationToken, поэтому я и стал надеяться на этот вариант, видя в нём выход.
Вот именно при закрытии формы как это воплотить? Т.е. как завершить поток там, где его не создавали (процедура)? Может этот момент поможете оформить? (в конце моего примера (первый пост вверху) закомментировано управление закрытием формы). Да, и желательно привязываться к Net 2, т.к. по умолчанию в XP "четвёрки" нет, а хотелось бы совместимости...
0
|
08.03.2016, 17:34 | 13 |
Раскомментировать метод. Прописать в нём установку переменной и вызвать метод Join() потока.
Чтобы иметь возможность обратиться к потоку, надо сохранить ссылку на него в приватных полях класса формы, а не забыть сразу после запуска. Т.е. переменная потока должна быть не локальной для метода.
0
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
08.03.2016, 17:47 [ТС] | 14 |
Rius, Дело в том, что потоки в приложении могут создаваться неоднократно, поэтому почитав уйму форумов, нашёл ответ - создание процесса в конкретной локальной процедуре, тогда исчезают множество проблем (создание новых процессов с новыми бесконечными именами, отказ создания с тем же именем, даже если предыдущий процесс уже завершён и т.д.). Поэтому у меня в коде поток создаётся в локальной процедуре, соответственно управление этим процессом невозможно из других процедур. Вот просьба, поясните эти слова:
, т.е. наоборот, - не "глобальной", а "приватной"?
0
|
08.03.2016, 17:55 | 15 |
Не знаю, что такое глобальная в VB.Net, но Вы именно этот способ уже исключили тут:
В этом случае можно применить свой task factory, коллекционирующий ссылки на запускаемые задачи и с методом ожидания завершения всех ещё незавершённых.
1
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
08.03.2016, 20:07 [ТС] | 16 |
Опять покажусь чайником , но у меня в коде выше нет никакого "task factory", поэтому
для меня неактуально, т.к. я понятия не имею что это такое, нигде ни в одной образовательной литературе такого, к сожалению, не встречал... Смотрел сейчас на форумах, лишь по C# пишут... Буду искать, конечно, дальше. Может когда найду, что это такое и где его применить в моём коде... Но всё-равно спасибо, что уделили мне время. Нельзя сказать что у меня пока нет вопросов, просто их так много, и становится всё больше, что лучше пока промолчу, изучу, а там "будем посмотреть".
0
|
08.03.2016, 20:17 | 17 |
Конечно нету, его надо написать. Класс для создания task/thread, который сохраняет ссылки на них, даже если наружу эти ссылки показывать не надо.
Можно и без этого, просто сохранять запущенные задачи в потокобезопасный список, например. И реализовать их самоудаление оттуда при завершении. Потому что потом удобно просигналить в один токен о необходимости завершения всех задач, и дождаться их завершения через Task.WaitAll(). Добавлено через 3 минуты
1
|
144 / 132 / 34
Регистрация: 28.02.2014
Сообщений: 159
|
|
08.03.2016, 20:36 | 18 |
Так может стоит использовать BackgroundWorker, т.к. там есть реальный способ остановить процесс выполнения операции?
0
|
Rius
|
08.03.2016, 20:40
#19
|
Не по теме: vova2112, у него есть другие неудобства. С момента его появления фреймворк слегка пополнился новыми классами.
0
|
0 / 0 / 0
Регистрация: 16.01.2016
Сообщений: 49
|
|
11.03.2016, 14:11 [ТС] | 20 |
vova2112, Ваш припер кода вверху завершает процедуру, но не завершает процесс при закрытии формы.
Rius, а ваш пример кода завершает все процессы при закрытии, но при попытке осмыслить код, не пойму где указывать (и добавлять в список) запускаемые потоки. Потому что многое в этом коде вижу в первый раз, для меня это "матюки" какие-то . Т.е. по моему приведённому (и сильно упрощённому) коду актуальных ответов практически не было. Повторюсь десятый раз - литературы обучающей по классам , озвученным Rius, не нашёл, и вообще мало-мальски поясняющей работу потоков, создание списка и т.д. Поэтому вопрос, конечно, остаётся открытым. Дело в том, что изучение современных языков программирования я как раз и начинал с C++ (после HTML), но ввиду моего начального знания английского, всё же решил не тратить время и изучить Visual Basic, поскольку его старшого брата - Basic 80-х знал в совершенстве, надеялся на некую "совместимость". Хотя признаюсь, на деле кроме совпадения в операторах и некоторых "командах" мало что осталось родственным.
0
|
11.03.2016, 14:11 | |
11.03.2016, 14:11 | |
Помогаю со студенческими работами здесь
20
Как правильно завершить поток сервера? Как правильно завершить поток QThread и выйти из него? Как правильно завершить поток (программа часы в Label) Как правильно завершить поток без исключения ThreadInterruptedException? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |