-1

У меня есть Task.Run(() => тут метод)
Как можно сделать чтобы метод выполнялся с нужным кол-во потоков ?
Или же тогда получается что задачи не нужны и оставить только Threads ?

ZidoX
  • 660
  • зачем? создай несколько Task – Grundy Nov 13 '22 at 13:27
  • Это как — с нужным количеством потоков? Task.Run(...) отправляет код на thread pool и там он бежит, как и любая синхронная функция, в одном потоке. Какая ваша проблема в точности? – VladD Nov 13 '22 at 13:27
  • @VlaD, а как разбить на несколько потоков? – ZidoX Nov 13 '22 at 13:28
  • 1
    @ZidoX: Контрвопрос — а как вы планировали делать это с Thread'ами? – VladD Nov 13 '22 at 13:29
  • https://ru.stackoverflow.com/q/1303748/373567 – aepot Nov 13 '22 at 15:24
  • Правильное решение зависит от конкретной задачи, конкретных данных и конкретных требований к производительности. – aepot Nov 13 '22 at 15:30

3 Answers3

3

Чтобы что то запускать с нужным количеством потоков - самый простой способ, это использовать TPL

Parallel.For(0, 10, new ParallelOptions() {MaxDegreeOfParallelism = 10 /* Нужное количесво потоков */}, (i) => {/* ваш метод */});
tym32167
  • 32,857
1
    public class Program
    {
        public static void Main()
        {

        Parallel.For(0, 3, new ParallelOptions() {MaxDegreeOfParallelism = 10}, (i) => {Run("хмм");}); //Взято из предыдущего комментария

        ParallelLoopResult result = Parallel.ForEach<int>(new List<int>() { 1, 3, 5, 8 }, Parallels); // Перебирает коллекцию в многопотоке

        Task[] tasks = new Task[3]; // Создаем массив задач
        for (int i = 0; i < tasks.Length; i++) //Перебираем задачи
        tasks[i] = Task.Factory.StartNew(() => Run("эмм")); //запускаем
        }

        static void Parallels(int n)
       {
        Console.WriteLine(n);
       }
        static void Run(string res)
        {
            Console.WriteLine(res);
        }

Вывод: хмм хмм хмм 1 5 3 8 эмм эмм эмм

xellan
  • 560
  • 3
  • 11
1

Более интересная реализация

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TaskRun { internal class JobManager : IDisposable { private SemaphoreSlim _semaphore; private CancellationTokenSource _cancelToken;

    public CancellationTokenSource CancellationTokenSource
    {
        get =&gt; _cancelToken ?? new CancellationTokenSource();
    }

    public async Task JobStart(List&lt;string&gt; list, Func&lt;string, Task&gt; action, int thread)
    {
        _semaphore = new SemaphoreSlim(thread);
        _cancelToken = new CancellationTokenSource();

        var pool = new List&lt;Task&gt;(thread);

        foreach (var item in list)
        {
            await _semaphore.WaitAsync().ConfigureAwait(false);

            pool.Add(Task.Run(() =&gt;
            {
                action(item);
                _semaphore.Release();
            }, _cancelToken.Token));
        }

        await Task.WhenAll(pool.ToArray()).ConfigureAwait(false);
    }

    public void JobStop()
    {
        _cancelToken.Cancel();
    }

    public void Dispose()
    {
        _semaphore?.Dispose();
        _cancelToken?.Dispose();
    }
}

}

Запуск в многопотоке

 JobManager _manager = new JobManager();
       var Data = new List<string>(){"Один", "Два"};
       await _manager.JobStart(Data, Work, 10); 
//10 число потоков, Work наш метод, Data - Передаем список в метод для обработки
        async Task Work(string iteam)
        {
         Console.Writeline(iteam);
        }
xellan
  • 560
  • 3
  • 11
  • А если у меня основной метод в void, делать async void нужно или async Task ? – ZidoX Nov 13 '22 at 20:55
  • @ZidoX void не поддерживает ожидание, то есть если вы напишете await TaskMethod() это будет не правильно, тогда вам нужно изначально писать метод Task. В кратце если вам не нужны методы Task, то пишете спокойно async void, а если будет хоть один метод Task не предвиденно, вам возможно придется переделать все методы в Task – xellan Nov 13 '22 at 23:49
  • Если вы будете из примера с JobManager использовать код, то он Настроен на Task, void в нем работать не будет, чтобы передавать туда void измените public async Task JobStart(List list, Func<string, Task> action, int thread) на public async Task JobStart(List list, Action action, int thread) – xellan Nov 13 '22 at 23:51