В документах для TPL я нашел эту строку:
Вызов нескольких продолжений из одного и того же прошлого
Но это не объясняетсядальшеЯ наивно полагал, что вы могли бы связать ContinueWiths аналогичным образом, пока вы не нажмете правую TaskContinuationOptions
.
TaskThatReturnsString()
.ContinueWith((s) => Console.Out.WriteLine(s.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((f) => Console.Out.WriteLine(f.Exception.Message), TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith((f) => Console.Out.WriteLine("Cancelled"), TaskContinuationOptions.OnlyOnCanceled)
.Wait();
Но это не сработает, как я надеялся, по крайней мере, двапричины.
- Продолжения правильно связаны, поэтому 2nd ContinueWith получает результат от 1st, который реализуется как новая задача, в основном сама задача ContinueWith.Я понимаю, что строка может быть возвращена вперед, но не будет ли это новой задачей с потерей другой информации?
- Поскольку первая опция не выполнена, задача просто отменяется.Это означает, что второй набор никогда не будет выполнен, а исключения потеряны.
Так что они имеют в виду в документах, когда говорят несколько продолжений от одного и того же происхождения?Для этого есть подходящий паттерн, или нам просто нужно обернуть вызовы в блоки try catch?
РЕДАКТИРОВАТЬ
Так что я думаю, это было то, что яя надеялся, что смогу это сделать, обратите внимание, что это упрощенный пример.
public void ProccessAllTheThings()
{
var theThings = util.GetAllTheThings();
var tasks = new List<Task>();
foreach (var thing in theThings)
{
var task = util.Process(thing)
.ContinueWith((t) => Console.Out.WriteLine($"Finished processing {thing.ThingId} with result {t.Result}"), TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((t) => Console.Out.WriteLine($"Error on processing {thing.ThingId} with error {t.Exception.Message}"), TaskContinuationOptions.OnlyOnFaulted);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
Поскольку это было невозможно, я подумал, что мне придется заключать каждый вызов задачи в цикл try внутри цикла, чтобы я не могОстановить процесс, но не ждать его там.Я не был уверен, какой правильный путь.
Иногда решение просто смотрит вам в лицо, это сработает, не так ли?
public void ProccessAllTheThings()
{
var theThings = util.GetAllTheThings();
var tasks = new List<Task>();
foreach (var thing in theThings)
{
var task = util.Process(thing)
.ContinueWith((t) =>
{
if (t.Status == TaskStatus.RanToCompletion)
{
Console.Out.WriteLine($"Finished processing {thing.ThingId} with result {t.Result}");
}
else
{
Console.Out.WriteLine($"Error on processing {thing.ThingId} - {t.Exception.Message}");
}
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}