Multi threads c#

Asked

Viewed 1,357 times

0

I would like to create a program to act multiple threads in a process, making 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);
    }
}
  • This code is very weird, probably has errors, but I can not say because I do not know the goal. The ideal is to use Task and not Thread and in this case run slower than done sequentially. https://answall.com/q/123173/101 and https://answall.com/q/1946/101

  • So the goal is to really respond if a multi-threaded application will do better, but I’m not getting multiple threads to work in the same process. (educational purposes)

  • Not to say only with an isolated case like this, for this your code, only the fact that the new thread allocates new features would slow down.

  • the code itself is not that, it’s just an example

2 answers

0


Use Thread 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#)

0

If its operations do not carry out IO, or if you cannot use the .net 4.5 or later, may make use of Parallel.For.

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

now you’re using the .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);
    }
}

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

But also partition their Tasks manually, but you will not have the aid of Parallel to calculate the optimal 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);
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.