0

I have a C# ASP.NET MVC project.
I am basically running a simulation (with an option to cancel) and collating the results.
I need to use multi-threading as I could run a million or more simulations at at time.
My code is like this:

public class MyClass
{
    private ConcurrentBag<StuffResult> StuffResults { get; set; }
    private bool CancellationRequested { get; set; }

    public void DoAlotOfStuff(int numberOfStuffToDo)
    {
        var cancellationTokenSource = new CancellationTokenSource();
        var options = new ParallelOptions { CancellationToken = cancellationTokenSource.Token };

        Task.Factory.StartNew(() =>
        {
            if (CancellationRequested) cancellationTokenSource.Cancel();
        });

        try
        {
            Parallel.For(0, numberOfStuffToDo, options, a =>
            {
                options.CancellationToken.ThrowIfCancellationRequested();
                var class1 = new Class1();
                var class2 = new Class2();
                var class3 = new Class3();
                var class4 = new Class4(class1, class2, class3);
                var result = class4.DoStuff();
                StuffResults.Add(result);
            });
        }
        catch (OperationCanceledException e)
        {
            //handle exception
        }
    }
}  

Question: How can I avoid instantiating a new Class1, Class2, Class3, and Class4 object for each iteration? I read this msdn article but I don't understand it. Perhaps 1 of each object per thread.

Th4t Guy
  • 1,442
  • 3
  • 16
  • 28

2 Answers2

0

It look safe enough to me...

If the classes have some kind of state involved with them then I don't know if you can avoid instantiating them. If not, you might be able to declare the classes outside the loop or make the DoStuff method static so you don't need an instantiated class at all.

NeilPearson
  • 128
  • 4
0

I would do it like this:

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

namespace ParallelTest
{
    class Program
    {
        static AutoResetEvent autoReset = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            // since this is an async method it will be run in a different thread
            DoSomething();

            // wait for the async method to signal the main thread
            autoReset.WaitOne();

            Console.WriteLine("done");

        }

        async static void DoSomething()
        {
            // create some common data
            const int count = 50000;
            const int factor = 3;


            // create some tasks
            var task1 = Task.Run(() =>
            {
                int x = 0;
                for (int i = 0; i < count * 2; ++i)
                {
                    x += i + factor * 3;
                    Console.WriteLine("task1: " + i + factor * 3);
                }
                return x;
            });

            var task2 = Task.Run(() =>
            {
                int x = 0;
                for (int i = 0; i < count * 2; ++i)
                {
                    x += i + factor * 4;
                    Console.WriteLine("task2: " + i + factor * 4);
                }
                return x;
            });

            var task3 = Task.Run(() =>
            {
                int x = 0;
                for (int i = 0; i < count * 2; ++i)
                {
                    x += i + factor * 5;
                    Console.WriteLine("task3: " + i + factor * 5);
                }
                return x;
            });


            // create a resulttask which will run all the tasks in parallel
            var resultTask = Task.WhenAll(task1, task2, task3);

            // start the task and wait till it finishes
            var results = await resultTask;

            // display the results
            for (int i = 0; i < results.Length; ++i)
            {
                Console.WriteLine("result" + i + ": " + results[i]);
            }

            // signal main thread
            autoReset.Set();
        }
    }
}