Код: Выделить всё
var TaksBag = new ConcurrentDictionary(); //I don’t know another standard solution for this collection
//some cyclic code begin
while (true) //For example, let be - an infinite loop
{
//First realization begin
Task tsk = null;
tsk = new Task(() => { var t = tsk; TasksBag.TryAdd(t, 0); SomeProcess(); TasksBag.TryRemove(t, out _); }); //Many “times” (points) in code
tsk.Start();
//First realization end
//or
//Perhaps this second realization is better begin
Task tsk = new Task(() => SomeProcess());
TasksBag.TryAdd(tsk, 0);
tsk.ContinueWith((t) => TasksBag.TryRemove(t, out _), TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.OnlyOnRanToCompletion);
tsk.Start();
//Perhaps this second realization is better end
}
//some cyclic code end
//Final point
var ta = TasksBag.Keys.ToArray();
Task.WaitAll(ta);
foreach (var tsk in ta)
TasksBag.TryRemove(tsk, out _);
//no exception processing for simplify; not needed if only hit once to this point (GC or app exit solve this)
< /code>
Есть ли какой -либо установлен код шаблона для следующей конструкции (для простоты, я опускаю шаблон отмены). < /p>
Может быть две различные архитектурные ситуации В последнем пункте: < /p>
Новые задачи не добавляются в коллекцию. И этот момент попадает только один раз, или < /li>
Новые задачи могут продолжать добавляться в коллекцию, но должны быть исключены из коллекции на этом этапе. Возможно, в этот момент все еще будет новый удар, а следующая обработка "waitall" < /li>
< /ol>
Есть ли общепринятое решение такой проблемы? Или упростить этот код? И это усложняет проблему после Waitall. var ta = TasksBag.Keys.ToArray();
Task.WaitAll(ta);
foreach (var tsk in ta)
TasksBag.TryRemove(tsk, out _); //no exception processing for simplify; not needed if only hit once to this point (GC or app exit solve this)
Кроме того, текст вопроса и код были скорректированы
Обновление #2 : это реально моя проблема: Обновление 3: Я думаю, это
//First realization begin
Task tsk = null;
tsk = new Task(() => { var t = tsk; TasksBag.TryAdd(t, 0); SomeProcess(); TasksBag.TryRemove(t, out _); }); //Many “times” (points) in code
tsk.Start();
//First realization end
< /code>
имеет потенциальную большую ошибку здесь < /p>
var t = tsk;
< /code>
Если я создам много задач, у которых не будет времени быстро завершить. Затем они будут в очереди до начала начала. И к тому времени, когда начнется исполнение, что будет в переменной "TSK"? Там будет «иностранная» задача! < /P>
Поэтому очень неправильно писать так. И я не знаю прямого способа получить ссылку на текущую задачу. Правда, здесь есть некоторые решения (и мне кажется, что у «лучшего решения» есть та же проблема, которую я определил). < /P>
Но ... конечно, в моем случае , текущая проблема может быть решена как -то < /p>
var tsk = new Task(() => { var t = TasksBag.Keys.FirstOrDefault(ts => ts.Id == Task.CurrentId); SomeProcess(u); if (t is not null) TasksBag.TryRemove(t, out _); });
TasksBag.TryAdd(tsk, 0);
tsk.Start();
Подробнее здесь: https://stackoverflow.com/questions/792 ... ent-in-net
Мобильная версия