Search code examples
c#multithreadingstopwatchconsole.readkey

Stopwatch and ReadKey don't work properly


I'm working on my multi-threading password cracker, only numbers. It must show how much time has passed to find the password. I used Stopwatch to find it, but in functions Stopwatch doesn't work. Here is my code:

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


namespace ConsoleApplication4
{
  class Program
  {
    static void Main(string[] args)
    {
        int psw = 14995399;

        Stopwatch time = new Stopwatch();

        Thread Thread1 = new Thread(islem1);
        Thread Thread2 = new Thread(islem2);
        Thread Thread3 = new Thread(islem3);
        Thread Thread4 = new Thread(islem4);

        time.Start();

        Thread1.Start();
        Thread2.Start();
        Thread3.Start();
        Thread4.Start();

        Thread.Sleep(1000);

        time.Stop();
        System.Console.WriteLine("Time elapsed: {0}", time.Elapsed);
        Console.ReadKey();
    }

    static void islem1()
    {
        for (int i = 00000000; i < 25000000; i++)
        {
            int psw = 14995399;
            if (i == psw)
            {
                System.Console.WriteLine("Şifre=" + i);

                time.Stop();
                Console.WriteLine("Time elapsed: {0}", time.Elapsed);
                Console.ReadKey();
            }
        }
    }

    static void islem2()
    {
        for (int i = 25000000; i < 50000000; i++)
        {
            int psw = 14995399;
            if (i == psw)
            {
                System.Console.WriteLine("Şifre=" + i);

                time.Stop();
                Console.WriteLine("Time elapsed: {0}", time.Elapsed);
                Console.ReadKey();
            }
        }
    }


    static void islem3()
    {
        for (int i = 50000000; i < 75000000; i++)
        {
            int psw = 14995399;
            if (i == psw)
            {
                System.Console.WriteLine("Şifre=" + i);

                time.Stop();
                Console.WriteLine("Time elapsed: {0}", time.Elapsed);
                Console.ReadKey();
            }
        }
    }

    static void islem4()
    {
        for (int i = 75000000; i < 100000000; i++)
        {
            int psw = 14995399;
            if (i == psw)
            {
                System.Console.WriteLine("Şifre=" + i);

                time.Stop();
                Console.WriteLine("Time elapsed: {0}", time.Elapsed);
                Console.ReadKey();
            }
        }
    }
  }
}

Solution

  • It's because your variable

    Stopwatch time = new Stopwatch();
    

    declared outside the visibility functions. The scope of visibility the var is your function Main. You can pass Stopwatch as a parameter to your functions:

    Thread1.Start(time);
    

    Or declare it as a class field:

    class Program
    {
        private static Stopwatch time = new Stopwatch();
        ...
    }
    

    Note that you have just one Stopwatch instance then if you stop it in one thread it'll stopped in all application and elapsed time will not changed after that.

    Then you should delete time.Stop(); from your Main method because it can caused the result in cased when your threads works longet then 1 second.

    Also it's no reason to call Thread.Sleep(). Just delete this lines and your code continues work as expected.

    Finally you can delete Console.ReadKey() from your thread functions because your main-thread already waits for user input.

    The whole solution with configurable threads count can illustrate interesting results for different number of threads. Try the code below which can illustrate work with thread parameters and reduce lines of code:

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace ConsoleApplication4
    {
        internal class Program
        {
            private class BruteforceParams
            {
                public int StartNumber { get; set; }
                public int EndNumber { get; set; }
            }
    
            private const int password = 14995399;
            private static readonly Stopwatch time = new Stopwatch();
    
            private static void Main(string[] args)
            {
                const int maxPassword = 100000000;
    
                Console.WriteLine("Enter number of threads: ");
                var threadsCountString = Console.ReadLine();
                var threadsCount = int.Parse(threadsCountString);
    
                var threads = new Thread[threadsCount];
                for (int i = 0; i < threadsCount; i++)
                {
                    var thread = new Thread(Bruteforce);
                    threads[i] = thread;
                }
    
                time.Start();
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i].Start(new BruteforceParams { StartNumber = i * maxPassword / threadsCount, EndNumber = (i + 1) * maxPassword / threadsCount });
                }
    
                Console.ReadKey();
            }
    
            private static void Bruteforce(object param)
            {
                var bp = (BruteforceParams) param;
                for (int i = bp.StartNumber; i < bp.EndNumber; i++)
                {
                    if (i == password)
                    {
                        Console.WriteLine("Şifre=" + i);
                        time.Stop();
                        Console.WriteLine("Time elapsed: {0}", time.Elapsed);
                    }
                }
            }
        }
    }