Завершение работы потока
От: Аноним  
Дата: 24.06.10 07:45
Оценка:
Как можно завершить работу потока в любом случае (необязательно безопасно)
Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.
System.Threading.Tasks.Task saveDataTask = new System.Threading.Tasks.Task(SaveBufferData);
saveDataTask .Start();


Заранее спасибо.
Re: Завершение работы потока
От: alexey.kostylev Новая Зеландия http://alexeykostylev.livejournal.com/
Дата: 24.06.10 07:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как можно завершить работу потока в любом случае (необязательно безопасно)

А>Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.
А>
А>System.Threading.Tasks.Task saveDataTask = new System.Threading.Tasks.Task(SaveBufferData);
А>saveDataTask .Start();
А>


А>Заранее спасибо.


Abort
Re[2]: Завершение работы потока
От: amirela  
Дата: 24.06.10 07:48
Оценка:
Здравствуйте, alexey.kostylev, Вы писали:

AK>Abort


Такого метода нет.
Re[3]: Завершение работы потока
От: alexey.kostylev Новая Зеландия http://alexeykostylev.livejournal.com/
Дата: 24.06.10 07:49
Оценка:
Здравствуйте, amirela, Вы писали:

A>Здравствуйте, alexey.kostylev, Вы писали:


AK>>Abort


A>Такого метода нет.



System.Threading.Thread th = ...
th.Abort();
Re[4]: Завершение работы потока
От: amirela  
Дата: 24.06.10 08:12
Оценка:
Здравствуйте, alexey.kostylev, Вы писали:
AK>
AK>System.Threading.Thread th = ...
AK>th.Abort();
AK>


Там не System.Threading.Thread, а System.Threading.Tasks.Task
Re: Завершение работы потока
От: _Dreamer Россия  
Дата: 24.06.10 08:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как можно завершить работу потока в любом случае (необязательно безопасно)

А>Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.

А>Заранее спасибо.


пример
пример 2

но если рабочий поток висит в какой-то блокирующей операции, я так понимаю, это не сработает.
у меня 2010 студии не стоит, не могу проверить.
Re: Завершение работы потока
От: _FRED_ Черногория
Дата: 24.06.10 09:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как можно завершить работу потока в любом случае (необязательно безопасно)

А>Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.

Обычно, "длительные операции при обращении к внешним ресурсам" имеют асинхронные способы вызова. В вашем случае есть способ вызвать такую длительную операцию асинхронно? А, может, там есть и метод отмены асинхронной операции?
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Завершение работы потока
От: amirela  
Дата: 24.06.10 11:11
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Аноним, Вы писали:


А>>Как можно завершить работу потока в любом случае (необязательно безопасно)

А>>Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.

_FR>Обычно, "длительные операции при обращении к внешним ресурсам" имеют асинхронные способы вызова. В вашем случае есть способ вызвать такую длительную операцию асинхронно? А, может, там есть и метод отмены асинхронной операции?


Да тут происходит запись в базу, при записи могут возникать блокировки, для такого случая и надо предусмотреть сброс потока.
Re[3]: Завершение работы потока
От: _FRED_ Черногория
Дата: 24.06.10 12:40
Оценка:
Здравствуйте, amirela, Вы писали:

_FR>>Обычно, "длительные операции при обращении к внешним ресурсам" имеют асинхронные способы вызова. В вашем случае есть способ вызвать такую длительную операцию асинхронно? А, может, там есть и метод отмены асинхронной операции?


A>Да тут происходит запись в базу, при записи могут возникать блокировки, для такого случая и надо предусмотреть сброс потока.


"Запись а базу" каким механизмом делается? В ADO.NET есть DBCommand, у которой есть CommandTimeout. Выставьте его в максимально допустимое для вас время — если не успеет, само отвалится. Если же хочется по кнопке пользователя отменить и вы используете SqlCommand для выполнения, то нужно использовать асинхронные методы вызова (например, BeginExecuteNonQuery), потом ждать или AsyncWaitHandle или события отмены . Отменить запрос уже не получится, но можно будет нормально прекратить нитку выполнения команды. Команду, увы, "нормально" завершить будт нельзя — для этого нет соответствующих механизмов.
Help will always be given at Hogwarts to those who ask for it.
Re: Завершение работы потока
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 24.06.10 21:35
Оценка: 9 (1) +1
Здравствуйте, Аноним, Вы писали:

А>Как можно завершить работу потока в любом случае (необязательно безопасно)

А>Пример, создается поток на обработку большого объема данных, в какой-то момент пользователю необходимо отменить выполнение. Как можно завершить работу потока в любом случае (даже с потерей обработанных данных). Использовать флаг, который сигнализирует об остановке задачи не получится т.к в процедуре обработки (SaveBufferData) имеются длительные операции при обращении к внешним ресурсам, а необходимо мгновенное завершение.

У Эрика Липперта была замечательная статья по этому поводу: Careful with that axe, part one: Should I specify a timeout?.

В .net не существует способа _гарантировано_ и _быстро_ завершить работу потока.

Здесь есть несколько сценариев, когда вам может понадобиться завершение потока.

Если код, который выполняется в другом потоке ваш, то лучше всего воспользоваться стандартной идиомой, разбить задачи на разумные этапы, установить тайм-аут подключения и т.п. и проверять флаг завершения или воспользоваться более формальным способом, благодаря таким классам как Task, CancellationTokenSource и CancellationToken (вот пример использования). Если у вас есть доступ к коду, то это самый разумный способ, при котором поведение при отмене некоторой операции будет максимально безопасным и предсказуемым.

Если же код, который выполняется в другом потоке не ваш, и вы не можете его изменить, то вы никак не сможете гарантировать его _быстрое_ завершение, поскольку Thread.Abort не прервет выполнение потока, если он выполняет CER, Unmanaged Code, Finally block. Так что, если в некотором потоке выполняется неизвестный вам код, то никто не сможет гарантирует ни корректное состояние приложения или ресурсов после принудительного завершения потока, ни вообще сам факт его завершения.

Существует еще один способ: можно получить идентификатор неуправляемого потока и прибить неуправляемый поток принудительно с помощью функции TerminateThread. Это будет быстро и работать будет всегда, но это отличный способ отстрелить себе ногу, так что пользоваться этим вариантом крайне не рекомендуется.
Re[4]: Завершение работы потока
От: amirela  
Дата: 25.06.10 02:30
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, amirela, Вы писали:


_FR>>>Обычно, "длительные операции при обращении к внешним ресурсам" имеют асинхронные способы вызова. В вашем случае есть способ вызвать такую длительную операцию асинхронно? А, может, там есть и метод отмены асинхронной операции?


A>>Да тут происходит запись в базу, при записи могут возникать блокировки, для такого случая и надо предусмотреть сброс потока.


_FR>"Запись а базу" каким механизмом делается? В ADO.NET есть DBCommand, у которой есть CommandTimeout. Выставьте его в максимально допустимое для вас время — если не успеет, само отвалится. Если же хочется по кнопке пользователя отменить и вы используете SqlCommand для выполнения, то нужно использовать асинхронные методы вызова (например, BeginExecuteNonQuery), потом ждать или AsyncWaitHandle или события отмены . Отменить запрос уже не получится, но можно будет нормально прекратить нитку выполнения команды. Команду, увы, "нормально" завершить будт нельзя — для этого нет соответствующих механизмов.


CommandTimeout мало какими DataProvider'ами поддерживается, BeginExecuteNonQuery — сейчас попробую.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.