M
M
More9162017-11-02 12:54:57
.NET
More916, 2017-11-02 12:54:57

How to implement an asynchronous task queue for an object in C#?

I can not understand in which direction to dig to implement asynchrony.
I will give explanations on an example:
Let's admit there is a class with a method which is being fulfilled a long time.

public class HardWorker : AbstractHardWorker
{
    public void DoSomething(int time)
    {
        Thread.Sleep(time);
    }
}

In the main program, five such objects are created, and then in a loop (for example, 50 times), this method is called for each object:
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));
    }
}

In this case, each hardWorker, before receiving a new method call, will be idle until the previous one completes the execution of its method.
I want to make sure that each hardWorker has its own queue of tasks, which it will sequentially execute asynchronously from other hardWorkers. Then it will be possible to distribute tasks to hardWorkers in the main thread and wait until they complete the execution of all tasks added to them. At the same time, for a windowed application (WinForms for example), the controls, and the entire window as a whole, will not hang during the execution of these lengthy tasks.
It is not possible to inherit the hardWorker class from BackgroundWorker, since it is already inherited from another class.
How to solve this problem using tasks and await/async modifiers?

Answer the question

In order to leave comments, you need to log in

4 answer(s)
L
lam0x86, 2017-11-03
@More916

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);
    }

C
cicatrix, 2017-11-02
@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

G
gibiw, 2017-11-02
@gibiw

async and await, no?
Here

S
stcmd04236, 2017-11-02
@stcmd04236

So create several threads in which tasks will be executed asynchronously. What is the difficulty?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question