Когда мне нужна параллельная обработка, я обычно делаю это так:
static void Main(string[] args)
{
var tasks = new List<Task>();
var toProcess = new List<string>{"dog", "cat", "whale", "etc"};
toProcess.ForEach(s => tasks.Add(CanRunAsync(s)));
Task.WaitAll(tasks.ToArray());
}
private static async Task CanRunAsync(string item)
{
// simulate some work
await Task.Delay(10000);
}
У меня были случаи, когда это не обрабатывало элементы параллельно и приходилось использовать Task.Run
чтобы заставить его работать в разных потоках.
Что мне не хватает?
Task
означает "то, что нужно сделать, что, возможно, уже выполнено, может выполняться в параллельном потоке или может зависеть от внепроцессных данных (сокетов и т.д.) Или может быть просто... подключено к переключиться куда-нибудь, что говорит "сделано" "- это имеет очень мало общего с многопоточностью, кроме: если вы запланируете продолжение (иначе await
), то каким-то образом потребуется вернуться к потоку для запуска, но как это происходит и что это означает, зависит от того, какой код создан и принадлежит задаче.
Примечание: параллелизм может быть выражен в терминах нескольких задач (если вы того пожелаете), но множественные задачи не подразумевают параллелизм.
В вашем случае: все зависит от того, что делает CanRun
или нет - а мы этого не знаем. Вероятно, он также должен называться CanRunAsync
.
Task.Run
или Task.Factory.StartNew
или просто добавляю асинхронный метод непосредственно в список задач, нет гарантии, что они будут работать в разных потоках?
CanRun
был расплывчатым: в общем случае : задача не означает поток.
Task
не являетсяThread
. На самом делеTask
может работать в exat жеThread
. Посмотрите на stackoverflow.com/questions/34375696/…CanRun
? Он запускает какие-либо задачи или возвращает холодные задачи?