More916
@More916

Как на C# реализовать асинхронную очередь задач у объекта?

Не могу понять в какую сторону копать для реализации асинхронности.
Пояснения приведу на примере:
Допустим имеется класс с методом, выполняющимся длительное время.
public class HardWorker : AbstractHardWorker
{
    public void DoSomething(int time)
    {
        Thread.Sleep(time);
    }
}

В основной программе создается пять таких объектов, и далее в цикле (например 50 раз), у каждого объекта вызывается данный метод:
static void Main(string[] args)
{
    HardWorker hardWorker1 = new HardWorker();
    ..........................................
    HardWorker hardWorker5 = new HardWorker();
    
    Random rand = new Random();
    
    for (int i=0; i < 50; i++)
    {
        hardWorker1.DoSomething(rand.Next(1,10000));
        .......................................
        hardWorker5.DoSomething(rand.Next(1,10000));
    }
}

В таком случае каждый hardWorker, прежде чем получить новый вызов метода, будет простаивать, пока предыдущий не завершит выполнение своего метода.
Я хочу сделать так, что бы у каждого hardWorker'a была своя очередь задач, которую он будет последовательно выполнять асинхронно от других hardWorker'ов. Тогда можно будет в основном потоке раздать hardWorker'ам задачи и ожидать пока они не завершат выполнение всех добавленных им задач . При этом для оконного приложения (WinForms например) элементы управления, да и все окно в целом не будет виснуть на время выполнения этих длительных задач.
Наследовать класс hardWorker от BackgroundWorker'а не возможно, так как он уже наследуется от другого класса.
Как решить данную задачу с использованием task'ов и модификаторов await/async?
  • Вопрос задан
  • 2346 просмотров
Решения вопроса 1
lam0x86
@lam0x86
class Program
    {
        static void Main(string[] args)
        {
            MainAsync(args).GetAwaiter().GetResult();

            Console.ReadKey();
        }

        static async Task MainAsync(string[] args)
        {
            HardWorker hardWorker1 = new HardWorker();
            HardWorker hardWorker2 = new HardWorker();
            HardWorker hardWorker3 = new HardWorker();
            HardWorker hardWorker4 = new HardWorker();
            HardWorker hardWorker5 = new HardWorker();

            Task t1 = Task.CompletedTask;
            Task t2 = Task.CompletedTask;
            Task t3 = Task.CompletedTask;
            Task t4 = Task.CompletedTask;
            Task t5 = Task.CompletedTask;

            Random rand = new Random();

            for (int i = 0; i < 50; i++)
            {
                t1 = t1.ContinueWith(task => hardWorker1.DoSomething(1, rand.Next(1, 10000)));
                t2 = t2.ContinueWith(task => hardWorker2.DoSomething(2, rand.Next(1, 10000)));
                t3 = t3.ContinueWith(task => hardWorker3.DoSomething(3, rand.Next(1, 10000)));
                t4 = t4.ContinueWith(task => hardWorker4.DoSomething(4, rand.Next(1, 10000)));
                t5 = t5.ContinueWith(task => hardWorker5.DoSomething(5, rand.Next(1, 10000)));
            }

            await Task.WhenAll(t1, t2, t3, t4, t5);
        }
    }

    public class HardWorker : AbstractHardWorker
    {
        public void DoSomething(int task, int time)
        {
            Console.Out.WriteLine("Start: " + task);
            Thread.Sleep(time);
            Console.Out.WriteLine("End: " + task);
        }
    }

    public interface AbstractHardWorker
    {
        void DoSomething(int task, int time);
    }
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@cicatrix
было бы большой ошибкой думать
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace TasksSample
{
    public class Worker
    {
        private int id;
        public Worker(int id)
        {
            this.id = id;
        }
        public void DoHardWork()
        {
            Console.WriteLine($"Task {this.id} started.");
            Random rng = new Random();
            int delay = rng.Next(1000, 10000);
            Thread.Sleep(delay);
            Console.WriteLine($"Task {this.id} finished after {delay} ms.");
        } // DoHardWork
    } // class Worker

    class Program
    {
        static void Main(string[] args)
        {
            TaskFactory fact = new TaskFactory();
            int TaskCount = 10;
            List<Task> myTasks = new List<Task>();
            for (int id = 0; id < TaskCount; ++id)
            {
                Worker w = new Worker(id);
                myTasks.Add(fact.StartNew(() => w.DoHardWork()));
            }
            Task.WaitAll(myTasks.ToArray());
        } // void Main
    } // class Program
} // namespace TasksSample
Ответ написан
@gibiw
async и await, не?
Тут
Ответ написан
@stcmd04236
Так создайте несколько потоков в котором задачи будет выполнятся асинхронно. В чем трудность?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы