
Летучая
18.06.2017
16:42:10
Боюсь таких картинок
Как огня

Alexander
18.06.2017
16:42:29
покажи пример как надо, я просто копипастил сам это

Летучая
18.06.2017
16:43:31
Убрать нечитаемые массивы и сделать обёрточку для итераций

Google

Влад
18.06.2017
16:47:09
Подниму чутка урон.
Чуть позже.

Igor
18.06.2017
16:48:47
Ну вы все таки сделайте отдельный чат или в @CSharpRest переместитесь, а тот тут не все дотеры.

Влад
18.06.2017
16:50:09
)(
Ты ток шо на урсе играл?

Anton
18.06.2017
16:58:31
Подскажите по CancellationToken. Как с ним правильно работать, чтобы не проверять на каждом шаге IsCancellationRequested?
Можно извне отменить таск, чтобы внутри него кинулся какой-нибудь CancellationRequestedException?
По типу Thread.Abort, только для тасков
Собственно такой эксепшен уже есть: OperationCanceledException, но сейчас его руками надо кидать, либо через token.ThrowIfCancellationRequested();. А это опять, получается, надо на каждом шаге писать. Хотелось бы, чтобы шедулер автоматически это делал

Роман
18.06.2017
17:08:44

Anton
18.06.2017
17:09:58
Мне кажется, что шедулер может
Он же это делает, когда прокидывает эксепшен из дочернего таска, когда его await'ишь

Роман
18.06.2017
17:12:37
Мне кажется, что шедулер может
если никакой магии нет, то шедулер не может, т.к. CancellationToken это просто объект, который никак не привязывается к потоку, а просто лежит на стеке
с исключением в дочернем потоке хотя бы понятно как работает, т.к. проброска исключения мало чем отличается от проброски возвращаемого значения

Google

Anton
18.06.2017
17:13:18
Хм
Но шедулер же вроде знает о токене
Потому что он даже не запускает таск, если токен отменён заранее
То есть, грубо говоря, в момент очередного пробуждения таска, он может проверить, если токен, ассоциированный с таском, отменён, то кинуть эксепшен
Но это мои догадки, я не смотрел, как шедулер написан
Просто мне казалось, что должен быть уже готовый механизм для этого
После каждого await проверять токен, это ужасный boilerplate

Дмитрий
18.06.2017
17:17:03
насколько я помню, при запуске таска проверяется IsCancellationRequested у токена
если true - таск не запускается и возвращается canceled task
вроде

Anton
18.06.2017
17:17:24
Ну да, он это делает в начале таска, при запуске
Значит, наверняка может делать каждый раз, когда пробуждает таск
Это я к тому, что связь между таском и токеном где-то там хранится всё-таки

Летучая
18.06.2017
17:18:43
Полгода назад задался тем же вопросом, хотел найти красивое решение
Не нашёл

Роман
18.06.2017
17:19:08

Дмитрий
18.06.2017
17:19:17
https://msdn.microsoft.com/ru-ru/library/dd321635(v=vs.110).aspx
может так попробовать?

Anton
18.06.2017
17:19:52
Да, про Register я знаю
Через него как раз можно делать высвобождение ресурсов при отмене

Дмитрий
18.06.2017
17:20:58
зарегать у токена делегат на метод, внутри которого всё стопать, чистить ресурсы и бросаться CanceledException-ом

Google

Anton
18.06.2017
17:20:59
А вот прерывать выполнение руками приходится

Gid
18.06.2017
17:21:34

Anton
18.06.2017
17:21:39
Да, я тоже так думал, но вроде все зарегистрированные экшены выполняются в том потоке, откуда вызван Cancel
И эксепшен соответственно тоже
А мне бы его прокинуть в continuation
Ну или хотя бы просто заставить его не вызывать этот самый continuation
Потому что всю логику по отмене можно запихать в token.Register(), а в таске надо просто return сделать

Дмитрий
18.06.2017
17:25:15
Я как-то с необходимостью такого никогда раньше не сталкивался...
обычно просто в ключевых точках IsCancellationRequested проверял

Anton
18.06.2017
17:26:43
Ну да, только не в ключевых точках, а после каждого await. И если их много, то это боль, и код становится плохочитаемым
Как будто не продумали они этот механизм до конца

Роман
18.06.2017
17:38:24

Летучая
18.06.2017
17:39:40
Есть чат, есть список диалогов
Если юзер выбирает диалог, а потом решает, что ему нужен другой диалог, а первый ещё не загрузился, в идеале задачу надо отменить и запустить новую
И вот тут такая штука бы пригодилась

Anton
18.06.2017
17:40:58

Летучая
18.06.2017
17:41:24
Должен же быть какой-нибудь способ прибить таск

Igor
18.06.2017
17:41:36

Летучая
18.06.2017
17:42:15
Примерно на таком вроде и остановился я в прошлый раз.

Google

Ilya
18.06.2017
17:44:00

Igor
18.06.2017
17:44:19

Ilya
18.06.2017
17:46:13
Вообще обычное использование токена это в безопасный момент проверять его и бросать экзепшн, по другому никак не сделать

Anton
18.06.2017
17:46:19
Ну сейчас примерно вот так получается:
{
try
{
var resource1 = await Load1();
token.ThrowIfCancellationRequested();
var resource2 = await Load2();
token.ThrowIfCancellationRequested();
var resource3 = await Load3();
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
{
if (resource1 != null)
resource1.Dispose();
if (resource2 != null)
resource2.Dispose();
if (resource3 != null)
resource3.Dispose();
throw;
}
}

Hell
18.06.2017
17:46:36
ВASP.NET MVC не используется по умолчанию EF?

Admin
ERROR: S client not available

Влад
18.06.2017
17:47:04
Кароч, релиз откладывается.

Anton
18.06.2017
17:47:04
Мне кажется логичным, что OperationCanceledException может и сам шедулер кидать, вместо меня

Влад
18.06.2017
17:47:12
Проблемы с хостингом. ?

Ilya
18.06.2017
17:47:19

Anton
18.06.2017
17:47:46

Ilya
18.06.2017
17:47:57

Anton
18.06.2017
17:49:04
Всё равно же придётся ThrowIfCancellationRequested вызывать

Igor
18.06.2017
17:49:12
Проблемы с хостингом. ?
А был бы докер контейнер, смог бы менять хостинги на раз два.
Деплой на чистый сервак за 1 минуту + 2 установка докера.

Ilya
18.06.2017
17:49:34
И сделать объект, в котором этот код написан idisposable и освобождать ресурсы в одном месте

Anton
18.06.2017
17:50:01
Вот так тогда будет:
{
try
{
var resource1 = await Load1(token);
token.ThrowIfCancellationRequested();
var resource2 = await Load2(token);
token.ThrowIfCancellationRequested();
var resource3 = await Load3(token);
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
{
if (resource1 != null)
resource1.Dispose();
if (resource2 != null)
resource2.Dispose();
if (resource3 != null)
resource3.Dispose();
throw;
}
}

Ilya
18.06.2017
17:50:06
При ошибке и при окончании использования этого объекта

Летучая
18.06.2017
17:50:25
Кстати, хорошая идея с подсунуть CancellationToken в долгие таски и обрабатывать их на месте, а не уровнем выше.

Google

Anton
18.06.2017
17:51:03

Ilya
18.06.2017
17:51:28
Третье не надо писать token.throw... сам метод бросит его

Anton
18.06.2017
17:51:29
Так прикол в том, что мне надо освободить ресурсы уже успешно завершившихся подтасков

Летучая
18.06.2017
17:51:30
HttpClient же принимает такие токены, как и многие другие таски из апи.
Например.

Ilya
18.06.2017
17:52:10

Anton
18.06.2017
17:53:05
Вызываю Dispose
Это вот то, что внутри catch

Ilya
18.06.2017
17:53:41
Дак на кой тебе их освобождать тут?

Anton
18.06.2017
17:54:00
А где?

Ilya
18.06.2017
17:54:28
В dispose методе объекта, где это код написан

Igor
18.06.2017
17:54:36

Anton
18.06.2017
17:54:44
В общем вопрос то и не стоит, где их освобождать
Вопрос в том, как сделать, чтобы не проверять отмену после каждого шага

Летучая
18.06.2017
17:56:13
И уже внутри них чекать отмену
Эта группа больше не существует