Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как остановить поток? не дожидаясь завершения 
V
    Опции темы
Warchief
Дата 18.12.2008, 04:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 24.5.2007

Репутация: нет
Всего: 3



Добрый день!

помогите разобраться с потоками. есть приложение, в котором при нажатии на баттон, стартует поток:

Код

 t = new Thread(new ThreadStart(delegate
            {
                MakeWork();
            }));
         
            t.Start();


Поток удачно стартует и работает. В теле функции MakeWork() есть следующий код,

Код

Thread.Sleep(int.Parse(textGetWaiter.Text));


который усыпляет поток.  В приложении есть кнопка, которая должна прерывать поток, пытаюсь делать так:

Код

t.Join();


Проблема в том, что поток не завершается, пока он находится в состоянии Sleep. И завершается только лишь после того, как поток пробудился. Такая-же проблема при закрытии приложения нажатием на "крестик в верху окна".

t.interrupt(), помогает, НО при закрытии приложения(когда Thread.Sleep(int.Parse(textGetWaiter.Text)); ещё не отработал) во время выполнения потока t, приложение пытается прочитать значение Thread.Sleep(int.Parse(textGetWaiter.Text)); и естественно не найдя его на форме, валится с ошибкой. 
PM MAIL ICQ Skype   Вверх
jonie
Дата 18.12.2008, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



есть Abort. по идее сгенерирует ThreadAbortException при достижении первой IL инструкции.... этот Exception делает rethrow в блоке catch, если не изменить явным образом то поведение. Однако этот Exception не является аварийным событием, так что сама программа не завершается


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mihryak
Дата 18.12.2008, 18:37 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 10
Всего: 36



посмотри в сторону EventWaitHandle
усыплять поток можно через
Код

public virtual bool WaitOne(
    int millisecondsTimeout,
    bool exitContext
)

при выходе из приложения нужно будет послать сигнал и вызвать thread.Join(), что разбудит поток и дождётся его корректного завершения
PM MAIL ICQ   Вверх
Warchief
Дата 18.12.2008, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 24.5.2007

Репутация: нет
Всего: 3



спасибо за ответы, но мне не важно чтобы поток завершался корректно, мне нужно его максимально быстро завершить.  Т.к. поток в основном спит по 30 секунд.
PM MAIL ICQ Skype   Вверх
PashaPash
Дата 18.12.2008, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



Warchief, вызывай вместо Sleep WaitOne c таймаутом 30 секунд. 


--------------------
PM MAIL WWW   Вверх
mihryak
Дата 18.12.2008, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 10
Всего: 36



Цитата(Warchief @  18.12.2008,  21:12 Найти цитируемый пост)
мне не важно чтобы поток завершался корректно, мне нужно его максимально быстро завершить.  Т.к. поток в основном спит по 30 секунд. 

ну тогда в моём решении между сигналом и tread.Join() делай thread.Abort()
PM MAIL ICQ   Вверх
mihryak
Дата 18.12.2008, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 10
Всего: 36



Код

    public partial class Form1 : Form
    {
        private readonly AutoResetEvent resetEvent = new AutoResetEvent(false);
        private readonly Thread thread;

        public Form1()
        {
            InitializeComponent();
            thread = new Thread(ThreadWork);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            thread.Start();
        }

        private void ThreadWork()
        {
            SomeWork();
            SetText("Sleeping...");
            resetEvent.WaitOne(int.Parse(textBox1.Text), false);
            SomeWork();
        }

        private void SomeWork()
        {
            for (int i = 0; i < 10000; i++)
            {
                SetText(i);
            }
        }

        private void SetText(object value)
        {
            Invoke(new MethodInvoker(delegate() { textBox2.Text = value.ToString(); }));
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (thread.ThreadState == ThreadState.Running || thread.ThreadState == ThreadState.WaitSleepJoin)
            {
                resetEvent.Set();
                thread.Abort();
            }
            thread.Join();
        }
    }

можешь ещё обратить внимание на свойство Thread.IsBackground
PM MAIL ICQ   Вверх
PashaPash
Дата 19.12.2008, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 9
Всего: 49



mihryak, а зачем в этом варианте Abort? достаточно if (resetEvent.WaitOne(...)) return;


--------------------
PM MAIL WWW   Вверх
mihryak
Дата 19.12.2008, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 10
Всего: 36



Цитата(PashaPash @  19.12.2008,  02:27 Найти цитируемый пост)
mihryak, а зачем в этом варианте Abort? достаточно if (resetEvent.WaitOne(...)) return; 

это на тот случай, если
Код
resetEvent.WaitOne(int.Parse(textBox1.Text), false);

уже прошёл, пошла остальная работа, и её надо тоже остановить
но проверка результата WaitOne и досрочный неаварийный выход - стоящая штука, не подумал как-то
_____________

ещё раз напомню про IsBackground
если не требуется особенная обработка завершения потока, то это свойство - самое то, что нужно, рантайм сам всё грамотно прибьёт

Это сообщение отредактировал(а) mihryak - 19.12.2008, 01:49
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0502 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.