Я работаю над своим многопоточным взломщиком паролей, только числами. Он должен показывать, сколько времени прошло на поиск пароля. Я использовал Секундомер, чтобы найти его, но в функциях Секундомер не работает. Вот мой код:

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();
            }
        }
    }
  }
}

Ответы (3)

Это потому, что ваша переменная

Stopwatch time = new Stopwatch();

объявлен вне функций видимости. Область видимости var - это ваша функция Main. Вы можете передать Секундомер в качестве параметра своим функциям:

Thread1.Start(time);

Или объявите его как поле класса:

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

Обратите внимание, что у вас есть только один экземпляр Stopwatch, тогда, если вы остановите его в одном потоке, он остановится во всех приложениях, и прошедшее время не изменится после этого.

Затем вы должны удалить time.Stop (); из вашего Main метода, потому что это может привести к результату, когда ваши потоки работают дольше 1 секунды.

Также нет причин вызывать Thread.Sleep (). Просто удалите эти строки, и ваш код продолжит работать должным образом.

Наконец, вы можете удалить Console.ReadKey () из функций вашего потока, потому что ваш основной поток уже ожидает ввода пользователя.

Все решение с настраиваемым количеством потоков может показать интересные результаты для разного количества потоков. Попробуйте приведенный ниже код, который может проиллюстрировать работу с параметрами потока и сократить количество строк кода:

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);
                }
            }
        }
    }
}

Будет сложно извлечь значимые тайминги с помощью одного экземпляра Stopwatch.

Вы можете выбрать измерения времени, используя другой шаблон, который использует новый секундомер для каждого измерения.

void Main()
{
    var t1 = new Thread(_ => {
        var sw = Stopwatch.StartNew();
        DoSomething();
        Console.WriteLine("took {0}ms", sw.ElapsedMilliseconds);
    });
    var t2 = new Thread(_ => {
        var sw = Stopwatch.StartNew();
        DoSomethingElse();
        Console.WriteLine("took {0}ms", sw.ElapsedMilliseconds);
    });
    t1.Start();
    t2.Start();
    t1.Join();
    t2.Join();
    Console.ReadKey();
}

void DoSomething()
{
    //do something
}

void DoSomethingElse()
{
    //do something
}

How do you think time.Stop(); going to work inside your function body islem1() or any other since you have defined the stopwatch inside Main() function body. You are bound to get compilation error saying time doesn't exist in current context.

static void islem1()
{
        .............
            time.Stop();  // this line of code
            Console.WriteLine("Time elapsed: {0}", time.Elapsed);
            Console.ReadKey();
        }
    }
}

Вместо этого вы можете создать отдельное наблюдение для каждого метода и сообщить, что

static void islem1()
{
      StopWatch time = Stopwatch.StartNew();
      time.Stop();  // this line of code
      Console.WriteLine("Time elapsed: {0}", time.Elapsed);
      Console.ReadKey();
 }

2022 WebDevInsider