powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / TPL. CancellationToken. Вопросы
6 сообщений из 6, страница 1 из 1
TPL. CancellationToken. Вопросы
    #38578234
MsSql_Study
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет.

Я похоже немного запутался. Есть пара вопросов.

1. Не могу уловить смысл передачи CancellationToken в метод Factory.StartNew ().

Код: c#
1.
2.
3.
var cts = new System.Threading.CancellationTokenSource();
var ct = cts.Token;
var t1 = Task.Factory.StartNew(() => Generate(ct), ct);



Зачем он передан в метод Generate понимаю (чтобы метод периодически его проверял). А зачем он передан отдельно в StartNew ?


2. Зачем нужно вызывать ThrowIfCancellationRequested ?
Только для того, чтобы у задачи появился статус Canceled ? Ведь можно проверять IsCancellationRequested и мирно завершать задачу.

Не совсем уловил, что происходит с исключением OperationCanceledException - нужно ли его ловить самому, или фреймворк его сам ловит.
Объясните пожалуйста русским языком этот момент с его тонкостями, когда там исключение нужно ловить, а когда нет :)

3. Мне нужно запустить таск, который будет крутится очень долго (дней 7 без останова, предположим) - там будет создание WCF хоста. Как я понимаю, в этом случае рекомендуется использовать TaskCreationOptions.LongRunning.

Так правильно ?

Код: c#
1.
Task MyTask = Task.Factory.StartNew(() => StartWork(token), token, TaskCreationOptions.LongRunning, TaskScheduler.Current);


Не нашел метода без передачи TaskScheduler, надеюсь я правильно его передаю.

И опять, зачем тут token второй раз передавать ? :)
...
Рейтинг: 0 / 0
TPL. CancellationToken. Вопросы
    #38578238
MsSql_Study
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PS. Есть мысль, что CancellationToken нужно передавать в StartNew именно для того, чтобы корректно работал ThrowIfCancellationRequested. Но механизм все же не совсем ясен. Объясните пожалуйста.
...
Рейтинг: 0 / 0
TPL. CancellationToken. Вопросы
    #38580198
MsSql_Study
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть ответы ? Или не только я не понимаю ? )
...
Рейтинг: 0 / 0
TPL. CancellationToken. Вопросы
    #38580216
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MsSql_Study,

Блин, просто заново копаться неохота, вспоминать. А неточные ответы только карму портят

Вот куски кода:
Код с сильными сокращениями
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
TaskFactory factory = new TaskFactory();
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource((int) WaitTimeout);
CancellationToken cancellationToken = cancellationTokenSource.Token;

// Теперь пробегаемся по всему списку клиентов.
// Важно: если будем в цикле анализировать длину очереди, это не поможет, тк очередь постоянно пополняемая, и будет зацикливание
int iterationCount = _connectionQueue.Count;
for (int i = 0; i < iterationCount; i++)
{
	KeyValuePair<Guid, ConnectionInfo> currentConnectionInfo;
	if (_connectionQueue.TryDequeue(out currentConnectionInfo))
	{
		factory
			.StartNew(
				stateObject => ProcessConnection(stateObject),
				new Tuple<CancellationToken, KeyValuePair<Guid, ConnectionInfo>>(cancellationToken, currentConnectionInfo),
				cancellationToken)
			.ContinueWith(       // тонкий момент: обратно в очередь закидываем только после УСПЕШНОГО окончания предыдущего таска, что обеспечивается TaskContinuationOptions.OnlyOnRanToCompletion
				previouseTask => _connectionQueue.Enqueue(previouseTask.Result), 
				TaskContinuationOptions.OnlyOnRanToCompletion);
	}
}



private KeyValuePair<Guid, ConnectionInfo> ProcessConnection(object stateObject)
{
	var typedState = (Tuple<CancellationToken, KeyValuePair<Guid, ConnectionInfo>>)stateObject;

	var token = typedState.Item1;
	var info = typedState.Item2.Value;

	try
	{
		if (false == token.IsCancellationRequested)
		{
			...
			// Какой то код
			...
		}

		token.ThrowIfCancellationRequested();

		return {РЕЗУЛЬТАТ} ;
	}
	catch (Exception ex)
	{
		// при любых ошибках грохаем соединение
		// при этом удаление из очереди обработки не делаем, так как сообщения в очереди отсутствует
		// но из словаря нужно вручную
		DeleteConnection(info);

		throw;
	}
}





MsSql_StudyCancellationToken нужно передавать в StartNew именно для того, чтобы корректно работал ThrowIfCancellationRequested
Это естественно

MsSql_StudyТолько для того, чтобы у задачи появился статус Canceled ? Ведь можно проверять IsCancellationRequested и мирно завершать задачу.
Нет, потому что есть цепочки тасков, последовательность вызова которых зависит от статуса завершения предыдущего
...
Рейтинг: 0 / 0
TPL. CancellationToken. Вопросы
    #38580324
MsSql_Study
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79,

Спасибо большое за прояснение.
Я пишу программу с использованием TPL. Приходится использовать и Continuations'ы. Разбирась вот.

Я уже увидел, что выброшенное исключение действительно влияет на цепочку. Местами мне это очень помогло, по другому даже не смог найти решения, пока не вспомнил про "продолжения".
Теперь ясно, что выброс исключения ставит программу не в статус Faulted а в Canceled. Хотя и так догадывался, но пока не использовал этот механизм, т.е. не убедился "практически", и не хотел случайно сломать программу написав код, который не понимаю.

Если подумать, я нарушил принцип в своей программе, т.к. останавливаю задачу через токенОтмены, но она при этом мирно завершается со статусом RanToCompletion :)

Буду разбираться и углублять знания дальше. Спасибо за помощь.

PS. А чего это вы "забыли" :) Tpl не оправдал надежд, и нашли что-то лучше ? Я вот думал о себе, что начав его применять перейду на него и это будет "основным режимом" так сказать, а некоторые смотрю уже отходят от него :)
...
Рейтинг: 0 / 0
TPL. CancellationToken. Вопросы
    #38580368
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MsSql_Study,

Вполне оправдал. Но я не каждый месяц пишу транспортные сервера. В мире много задач, которые требуют иных подходов
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / TPL. CancellationToken. Вопросы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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