Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Task/asynс/await и прерывание синхронного метода / 23 сообщений из 23, страница 1 из 1
04.07.2014, 13:44
    #38687942
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Что-то никак не врублюсь, как убить синхронный метод.

Делаю "отзывчивый" интерфейс winforms с возможностью пользователю прервать выполнение задачи.
В приведенном примере метод SyncLock имитирует долгий синхронный метод, внутрь которого я влезть не могу.

Если пользоваться по старинке потоками, я его спокойно убиваю через thread.Abort(), обрабатываю исключение прерывания и спокойно завершаю задачу.
В примерах с async/await приводится опрос токена, но я ведь не могу его проводить внутри чужого синхронного метода. Подскажите, где я не догоняю?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
    private CancellationTokenSource cts;


    private void btStart_Click(object sender, EventArgs e)
    {
      StartAsync();
    }
    private void btStop_Click(object sender, EventArgs e)
    {
      cts.Cancel();
    }

    private async void StartAsync()
    {
      cts = new CancellationTokenSource();
      await Tasker(cts.Token);
    }
    
    private Task Tasker(CancellationToken ct)
    {
      return Task.Run(new Action(() =>
      {
        // какие-то действия
        SyncLock();
        // какие-то другие действия
      }), ct);
    }

    private void SyncLock()
    {
      Thread.Sleep(5000);
    }
...
Рейтинг: 0 / 0
04.07.2014, 14:59
    #38688040
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Основных варианта два:

1. Если асинхронная операция самописная - в одном из циклов обращаться к CancellationToken на предмет отмены.

2. Если асинхронная операция содержит вложенную асинхронную операция (асинхронное обращение к БД, сокету и т. п.) - передавать CancellationToken во вложенную асинхронную операцию.
...
Рейтинг: 0 / 0
04.07.2014, 15:08
    #38688049
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Еще раз.
у меня есть СИНХРОННАЯ чужая операция.
Я не могу влезть к ней внутрь.
В примере подобную операцию представляет SyncLock

Вопрос конкретно по примеру. Можно ли прервать выполнение SyncLock до его реального завершения (не внося изменения в SyncLock) используя работу с Task-ами?
...
Рейтинг: 0 / 0
04.07.2014, 15:12
    #38688057
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProЕще раз.
у меня есть СИНХРОННАЯ чужая операция.
Я не могу влезть к ней внутрь.Тогда никак. Только Thread.Abort.
...
Рейтинг: 0 / 0
04.07.2014, 15:28
    #38688083
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Получается тогда ерунда? Сделали Task, наворотили сахарных конструкций, при этом потерялась возможность насильно прервать выполнение?
...
Рейтинг: 0 / 0
04.07.2014, 15:54
    #38688116
pation
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProПолучается тогда ерунда? Сделали Task, наворотили сахарных конструкций, при этом потерялась возможность насильно прервать выполнение?
ерунду сморозил, ничто не потерялось, а Thread.Abort - зло
...
Рейтинг: 0 / 0
04.07.2014, 15:56
    #38688117
cdtyjv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProЕще раз.
у меня есть СИНХРОННАЯ чужая операция.
Я не могу влезть к ней внутрь.
В примере подобную операцию представляет SyncLock

Вопрос конкретно по примеру. Можно ли прервать выполнение SyncLock до его реального завершения (не внося изменения в SyncLock) используя работу с Task-ами?У вас принципиальное непонимание того, как работает программа. Поток - это набор инструкций. Его нельзя взять, и остановить в произвольном месте. Любая операция по нормальной остановке какой-либо задачи выглядит следующем образом:
1) Когда вам надо остановить задачу, вы выставляете где-то флажок, что надо остановиться.
2) Сама задача периодически проверяет этот флажок, и если видит, что надо остановиться - останавливается.
Принципиально так реализовано все. Так реализованы прерывания IO операций, так реализованы прерывания через CancellationToken, так реализованы прерывания ожидания всяких критических секций и условий, и т.д.. Разумеется, конечная реализация может отличаться - где-то это просто managed-переменная, где-то вызов какого-нибудь WinAPI, где-то вызов прерывания, и т.д.. Но суть одна - "первый поток ставит флажок, второй поток читает флажок".

Вы же прерываете поток через Abort(). Это плохая, отвратительная практика. В Java, например, это вообще запрещено. И правильно, что запрещено - это дурной тон! А что, если ваш поток, например, сидел внутри критической секции и должен был консистентно изменить две переменные, а вы вызвали Abort, и он смог изменить только одну, оставив систему в неконсистентном состоянии? Abort() используют либо от лени, либо от непонимания.

Если вас по каким-то причинам не устраивает cancellation token, то сделайте какой-нибудь volatile bool - один поток выставляет его, второй читает.
...
Рейтинг: 0 / 0
04.07.2014, 16:05
    #38688127
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Ну так при прерывании потока возникает эксепшен, вызывается финализатор, где я могу привести все в правильное состояние (в моем случае нужно только вернуть кнопку Start в состояние Enabled, а кнопку Stop - в disabled).

cdtyjvЕсли вас по каким-то причинам не устраивает cancellation token, то сделайте какой-нибудь volatile bool - один поток выставляет его, второй читает.как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop?
...
Рейтинг: 0 / 0
04.07.2014, 17:02
    #38688215
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProПолучается тогда ерунда? Сделали Task, наворотили сахарных конструкций, при этом потерялась возможность насильно прервать выполнение ?А она была, если забыть о thread.abort?
...
Рейтинг: 0 / 0
04.07.2014, 17:10
    #38688229
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
А почему о нем надо забыть?
Еще раз. Как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop?
...
Рейтинг: 0 / 0
04.07.2014, 17:20
    #38688253
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProА почему о нем надо забыть?
Еще раз. Как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop?
В обработчике клика поставьте
Код: c#
1.
System.Diagnostics.Process.Start("ShutDown", "/r");


Правда будут некоторые побочные эффекты :)
...
Рейтинг: 0 / 0
04.07.2014, 17:23
    #38688260
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
cdtyjv,

Вам в слове «чужая», что не понятно?
...
Рейтинг: 0 / 0
04.07.2014, 17:23
    #38688261
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProА почему о нем надо забыть?
Еще раз. Как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop?

а зачем прерывать? долго выполняется и блокируется GUI ?
если так, то запускай задание на выполнение и всё, интерфейс свободен, а останавливать его уже пользователю не надо давать, это не его дело. контролируй уже завершение самой задачи и выводи в пользовательский GUI инфу по событию
...
Рейтинг: 0 / 0
04.07.2014, 17:31
    #38688279
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProА почему о нем надо забыть?Ладно, проехали...
Shocker.ProЕще раз. Как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop? 16260553
...
Рейтинг: 0 / 0
04.07.2014, 17:57
    #38688304
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
ЕвгенийВВ обработчике клика поставьте
Код: c#
1.
System.Diagnostics.Process.Start("ShutDown", "/r");

это перезапустит всю прогу что ли? нафиг это надо, мне всего лишь надо прекратить выполнение задачи.


Алексей КShocker.ProЕще раз. Как мне дать возможность пользователю прервать синхронную операцию, нажав кнопку stop? 16260553 но это тогда означает, что я не могу использовать преимущества Task? Или можно как-то получить тред из таска?

Konst_Oneа зачем прерывать? долго выполняется и блокируется GUI ?Ну так да.Konst_Oneесли так, то запускай задание на выполнение и всё, интерфейс свободен, а останавливать его уже пользователю не надо давать, это не его дело. контролируй уже завершение самой задачи и выводи в пользовательский GUI инфу по событиюну можно, конечно, но как-то странно, висит никому не нужный процесс, что-то делает, грузит ввод-вывод, процессор....
...
Рейтинг: 0 / 0
04.07.2014, 18:03
    #38688308
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.Proну можно, конечно, но как-то странно, висит никому не нужный процесс, что-то делает, грузит ввод-вывод, процессор....

нужный, раз клиент кнопку нажал на запуск
...
Рейтинг: 0 / 0
04.07.2014, 18:03
    #38688309
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProАлексей Кпропущено...
16260553 но это тогда означает, что я не могу использовать преимущества Task? Или можно как-то получить тред из таска?Это можно завернуть в Task, добавятся определённые удобства. Но чудес не бывает, внутри всё равно будет использоваться thread.abort.
...
Рейтинг: 0 / 0
04.07.2014, 18:20
    #38688323
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.ProЕвгенийВВ обработчике клика поставьте
Код: c#
1.
System.Diagnostics.Process.Start("ShutDown", "/r");

это перезапустит всю прогу что ли? нафиг это надо, мне всего лишь надо прекратить выполнение задачи.

Нет, это перегрузит весь комп, прогу перезапустит
Код: c#
1.
Application.Restart()
...
Рейтинг: 0 / 0
04.07.2014, 18:36
    #38688333
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Ок, я получил ответ на свой вопрос.
Я нарочно задал его в обобщенном виде, чтобы понимать, как в принципе поступают в таких случаях.


В продолжение есть конкретный вопрос. На самом деле этим длинным методом является метод обращения к веб-сервису. Я никогда с ними не работал, попросили на коленке по-быстрому сделать скачку информации, я кинул в студию WSDL-файл, получил методы запустил-скачал.

Но, так как методы работают заметное время и возникает блокировка интерфейсов, полез смотреть, как работать с многопоточностью, в результате чего и возник этот топик.

Если же предполагаются, что методы .NET, связанные с обменом и могущие занимать много времени, работают с CancellationToken, то как мне быть в данном случае для создания возможности отмены выполнения WEB-метода? методы выполняются через экземпляр System.ServiceModel.ClientBase<>, который сгенерился автоматически.
...
Рейтинг: 0 / 0
04.07.2014, 18:55
    #38688352
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
...
Рейтинг: 0 / 0
04.07.2014, 19:00
    #38688361
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
спасибо. Доберусь теперь уж только в понедельник.
...
Рейтинг: 0 / 0
04.07.2014, 19:07
    #38688370
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Shocker.Pro,
авторметоды работают заметное время и возникает блокировка интерфейсов
асинхронность ?
...
Рейтинг: 0 / 0
04.07.2014, 21:01
    #38688450
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Task/asynс/await и прерывание синхронного метода
Где-то в степиасинхронность ?см. топик с первого сообщения ))
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Task/asynс/await и прерывание синхронного метода / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]