Всем привет. У меня есть два вопроса:
1)
Мне нужен алгоритм с Task'ами который будет выбирать объекты из массива и для каждого объекта в отдельном потоке выполнять некоторые действия. Количество одновременно работающих потоков при этом должно быть ограничено.
Написал такой вариант:
class TestObject
{
public TestObject(string value)
{
Value = value;
}
public string Value { get; set; }
}
class Program
{
const int maxTasksCount = 5;
static void Main()
{
CancellationTokenSource abortToken = new CancellationTokenSource();
List<TestObject> testObjects = new List<TestObject>();
for (int i = 0; i < 20; i++)
{
testObjects.Add(new TestObject(i.ToString()));
}
var task = Task.Run(() =>
{
List<Task> tasks = new List<Task>();
lock (testObjects)
{
foreach (var obj in testObjects)
{
if (abortToken.IsCancellationRequested)
return;
if (tasks.Count >= maxTasksCount)
{
var index = Task.WaitAny(tasks.ToArray());
tasks.RemoveAt(index);
}
tasks.Add(Task.Run(() => Work(obj, abortToken)));
}
}
Task.WaitAll(tasks.ToArray());
});
task.Wait();
foreach (var obj in testObjects)
Console.Write(obj.Value);
Console.ReadLine();
}
static void Work(TestObject obj, CancellationTokenSource abortToken)
{
lock (obj)
{
Thread.Sleep(1000);
obj.Value = "!"; // Типа полезная работа
if (abortToken.IsCancellationRequested)
return;
}
}
}
Алгоритм работает, но есть сомнения. Подскажите на сколько правильно я всё сделал и что нужно поправить.
2)
На сколько верно в подобных задачах для приостановки выполнения Task'a использовать ManualResetEvent? Я тут где то вычитал мнение, что Task != Thread и в общем случает один Thread может выполнять несколько Task'ов и один Task может быть размазан по нескольким Thread'ам. На сколько это верно. Под Task'ом я здесь понимаю, элементарный Task без вложенных задач.