0

trying to find 100000! using biginteger, stack and without using task library. Threads are randomly taking others args and break the program. How to make them organized but parallel?

    class Program
    {
        
        static readonly int DegreeOfParallelism = Environment.ProcessorCount;
        Stack<BigInteger> numbers = new Stack<BigInteger>(DegreeOfParallelism);
        public BigInteger Factorial(BigInteger x)
        {
            for (int i = 1; (i <= DegreeOfParallelism && i <= x); i++)
            {
                Thread thread = new Thread(() => { Multiply(x, i); });
                thread.Name = $"thread{i}";
                thread.Start();
            }
            Thread.Sleep(1000);
            BigInteger finalResult = 1;
            while (numbers.Count>0)
            {
                finalResult *= numbers.Pop();
            }
            return finalResult;
        }
        void Multiply(BigInteger upperBound, int startFrom)
        {
            BigInteger result = 1;
            for (BigInteger j = startFrom; j <= upperBound; j += DegreeOfParallelism)
            {
                result *= j;
                Console.WriteLine("res = {0}", result);
            }
            numbers.Push(result);
            Console.WriteLine(numbers.Peek());
            Console.WriteLine(Thread.CurrentThread.Name);
        }
        static int Main()
        {
            BigInteger n = 0;
            Console.WriteLine("Write a number");
            n = Convert.ToInt64(Console.ReadLine());
            var program = new Program();
            Console.WriteLine(program.Factorial(n));
            return 0;
        }
    }
Svengali
  • 1
  • 1
  • Threads are randomly taking other args? Huh? And why are you instantiating your whole class again? You're already in Program – gilliduck Oct 16 '22 at 21:54
  • @gilliduck could you please suggest *another* way to describe what should be happening with that `for` loop? I assume you understand that code as written will not behave as desired (or even predictably), so my guess your comment is about word choice. (As for creating instance of `Program` - it is much easier to try multiple variants when you have instance variables, but for [mre] packing everything into single `Program` class and newing it up sounds like a reasonable approach... ) – Alexei Levenkov Oct 16 '22 at 22:11
  • Svenfali - duplicate explains why `for` behaves that way. To get correct code you need to put back your locking code that you presumably removed for [mre]. – Alexei Levenkov Oct 16 '22 at 22:14
  • For in factorial creating threads and giving them method multiply where i is like id but they are usually working with others id, or even with only one for all – Svengali Oct 17 '22 at 04:51
  • I don't know C#, but I bet `Thread.sleep(1000)` is _not_ the right way to wait for other threads to finish their work. (Maybe especially not the right way to wait if part of the "work" that each thread does includes writing thousands of lines to the `Console`.) – Solomon Slow Oct 17 '22 at 15:31

0 Answers0