2016-01-01 8 views
-2

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

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

Создайте отдельный «секундомер» в каждой из ваших функций потока. Не создавайте ни одного и делитесь им между потоками. –

+2

Это не * «не работает» *, это * «не компилируется» *. Это огромная разница. –

ответ

4

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

Stopwatch time = new Stopwatch(); 

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

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

спасибо, сэр, я исправил его, я новичок в codding, я не могу все думать .. –

+0

Я не уверен, что я понимаю ваш сценарий, но я думаю, что вам не нужно получать ReadKey в каждой функции потока.Попытайтесь удалить его, и он будет продолжать работать, как я полагаю. Также удалите time.Stop(); line от главной функции. –

+0

Это не все, что полезно для OP, потому что они несколько раз вызывают 'Stop' на одном экземпляре секундомера. Это приведет к неожиданным результатам. – spender

1

Как вы думаете, time.Stop(); будет работать внутри тела функции islem1() или любых других, так как вы определили секундомер внутри Main() тела функции. Вы обязаны получить ошибку компиляции, так как time не существует в текущем контексте.

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

спасибо, сэр, я исправил его, я новичок в codding, я не могу все мыслить. –

0

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

Возможно, вы захотите выполнить ваши измерения времени с использованием другого шаблона, который использует новый 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 
}