Multi threads C #

0

I would like to create a program to act on multiple threads in a process, leaving it faster, that is, the threads working together to finish the service faster. But each one works individually in the process.

Sample code:

class Program
{
    static void Main(string[] args)
    {
        Soma s = new Soma();
        Thread[] Threads = new Thread[5];
        for (int i = 0; i < 5; i++)
        {
            Threads[i] = new Thread(new ThreadStart(s.PrintNumbers));
        }

        foreach (Thread t in Threads)
            t.Start();


        Console.ReadLine();
    }
}
class Soma
{
    double soma = 0;
    public void PrintNumbers()
    {
        for (int i = 0; i < 5; i++)
        {
            if (i%2 != 0)
            {
                soma -= i;
            }
            else
            {
                soma += i;
            }
        }
        Console.WriteLine(soma);
    }
}
    
asked by anonymous 24.10.2017 / 16:17

2 answers

0

Use Threads Pools. Example:

using System;  
using System.Threading;  

public class Fibonacci  
{  
    private int _n;  
    private int _fibOfN;  
    private ManualResetEvent _doneEvent;  

    public int N { get { return _n; } }  
    public int FibOfN { get { return _fibOfN; } }  

    // Constructor.  
    public Fibonacci(int n, ManualResetEvent doneEvent)  
    {  
        _n = n;  
        _doneEvent = doneEvent;  
    }  

    // Wrapper method for use with thread pool.  
    public void ThreadPoolCallback(Object threadContext)  
    {  
        int threadIndex = (int)threadContext;  
        Console.WriteLine("thread {0} started...", threadIndex);  
        _fibOfN = Calculate(_n);  
        Console.WriteLine("thread {0} result calculated...", threadIndex);  
        _doneEvent.Set();  
    }  

    // Recursive method that calculates the Nth Fibonacci number.  
    public int Calculate(int n)  
    {  
        if (n <= 1)  
        {  
            return n;  
        }  

        return Calculate(n - 1) + Calculate(n - 2);  
    }  
}  

public class ThreadPoolExample  
{  
    static void Main()  
    {  
        const int FibonacciCalculations = 10;  

        // One event is used for each Fibonacci object.  
        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];  
        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];  
        Random r = new Random();  

        // Configure and start threads using ThreadPool.  
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);  
        for (int i = 0; i < FibonacciCalculations; i++)  
        {  
            doneEvents[i] = new ManualResetEvent(false);  
            Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);  
            fibArray[i] = f;  
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);  
        }  

        // Wait for all threads in pool to calculate.  
        WaitHandle.WaitAll(doneEvents);  
        Console.WriteLine("All calculations are complete.");  

        // Display the results.  
        for (int i= 0; i<FibonacciCalculations; i++)  
        {  
            Fibonacci f = fibArray[i];  
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);  
        }  
    }  
} 

Source: How to use a thread pool (C #)

    
24.10.2017 / 16:44
0

If your operations do not perform IO operations, or you can not use .net 4.5 or later, you can use Parallel.For .

var s = new Soma();
Parallel.For(0, 5, i => PrintNumbers());

Now if you are using .net 4.5 or later, you can use the magic words async/await .

static void Main(string[] args)
{
    Task.Run(Exec).GetAwaiter().GetResult();
}

static async Task Exec()
{
    var s = new Soma();
    var tasks = new Task[5];
    for (int i = 0; i < 5; i++)
        tasks[i] = s.PrintNumbers();
    await Task.WhenAll(tasks);
}

class Soma
{
    double soma = 0;
    public async Task PrintNumbers()
    {
        await Task.Yield();
        for (int i = 0; i < 5; i++)
        {
            if (i%2 != 0)
            {
                soma -= i;
            }
            else
            {
                soma += i;
            }
        }
        Console.WriteLine(soma);
    }
}

While Parallel.For has an advantage over async/await , it creates internal partitioning to avoid creating more Threads than necessary.

But also partition your Tasks manually, but you will not have to Parallel to calculate the ideal number of partitions.

static void Main(string[] args)
{
    Task.Run(Exec).GetAwaiter().GetResult();
}

static async Task Exec()
{
    var s = new Soma();
    var particoes = 3;
    var tasks = Enumerable.Range(0, particoes).Select(x => Task.CompletedTask).ToArray();
    for (int i = 0; i < 7; i++)
    {
        var particao = i % particoes;
        tasks[particao] = tasks[particao].ContinueWith(async t => await s.PrintNumbers());
    }           
    await Task.WhenAll(tasks);
}

class Soma
{
    double soma = 0;
    public async Task PrintNumbers()
    {
        await Task.Yield();
        for (int i = 0; i < 5; i++)
        {
            if (i%2 != 0)
            {
                soma -= i;
            }
            else
            {
                soma += i;
            }
        }
        Console.WriteLine(soma);
    }
}
    
24.10.2017 / 18:10