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

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

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
04.03.2014, 19:32
    #38578238
MsSql_Study
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TPL. CancellationToken. Вопросы
PS. Есть мысль, что CancellationToken нужно передавать в StartNew именно для того, чтобы корректно работал ThrowIfCancellationRequested. Но механизм все же не совсем ясен. Объясните пожалуйста.
...
Рейтинг: 0 / 0
06.03.2014, 14:16
    #38580198
MsSql_Study
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TPL. CancellationToken. Вопросы
Есть ответы ? Или не только я не понимаю ? )
...
Рейтинг: 0 / 0
06.03.2014, 14:31
    #38580216
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TPL. CancellationToken. Вопросы
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
06.03.2014, 15:28
    #38580324
MsSql_Study
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
TPL. CancellationToken. Вопросы
Arm79,

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

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

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

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

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

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


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