Закрытие значения внутри метода потока - PullRequest
0 голосов
/ 02 мая 2018

Здравствуйте, я пытаюсь передать текущий индекс цикла внутри лямбда-метода потока и распечатать его. Метод выведет только последнее значение индекса.

class Program {
        public static EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
        public static EventWaitHandle autohandle = new EventWaitHandle(false, EventResetMode.AutoReset);
        static readonly int ThreadNum=3;

        static void Main(string[] args) {
            object lk = new object();
            new Thread(() => {

                while (true) {

                    var key = Console.ReadKey();
                    if(key.Key==ConsoleKey.A) {
                        handle.Set();
                    } else {
                        handle.Reset();
                    }
                    Thread.Sleep(3000);


                }
            }).Start();

            for(int i=0;i<ThreadNum;i++) {

                new Thread(() => {
                    int val = i;
                    Console.WriteLine($"Thread:{val} created");
                    while (true) {

                        handle.WaitOne();

                        Console.WriteLine($"From thread:{val}");
                        Thread.Sleep(1000);
                    }
                }).Start();
            }

            Console.WriteLine("Hello World!");
        }

    }

Может ли кто-нибудь объяснить мне, почему я получу только последнее значение индекса. Я понимаю, что индекс закрывается (создается класс, который копирует значение индекса), но когда первая итерация входит в метод потока, она должна закрывать = 0 и продолжайте в том же духе.

1 Ответ

0 голосов
/ 02 мая 2018

Я думаю, что поведение, которое вы видите, связано с тем, что цикл повторяется до того, как назначена локальная переменная 'val'. Так что к тому времени заявление

int val = i;

выполняется в первый раз, цикл уже повторялся 3 раза, поэтому вы устанавливаете 'val' в последнее значение i. Когда я запускаю его, я получаю переменное поведение из-за относительной скорости, с которой создаются потоки. Чтобы получить поведение, которое, я думаю, вам нужно, вам нужно локально записать количество итераций цикла, например:

  class Program
  {
    public static EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
    public static EventWaitHandle autohandle = new EventWaitHandle(false, EventResetMode.AutoReset);
    static readonly int ThreadNum = 3;

    static void Main(string[] args)
    {
      object lk = new object();
      new Thread(() => {

        while (true)
        {

          var key = Console.ReadKey();
          if (key.Key == ConsoleKey.A)
          {
            handle.Set();
          }
          else
          {
            handle.Reset();
          }
          Thread.Sleep(3000);


        }
      }).Start();

      for (int i = 0; i < ThreadNum; i++)
      {
        int temp = i;
        new Thread(() => ThreadMethod(temp)).Start();
      }

      Console.WriteLine("Hello World!");
    }
    private static void ThreadMethod(object obj)
    {
      int val = (int)obj;
      Console.WriteLine($"Thread:{val} created");
      while (true)
      {

        handle.WaitOne();

        Console.WriteLine($"From thread:{val}");
        Thread.Sleep(1000);
      }
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...