Как заблокировать свойство сеттера для потока - PullRequest
1 голос
/ 30 июня 2010

Я использую четыре потока, которые получают и устанавливают одно и то же свойство.Когда я использую точку останова, тогда это дает мне ожидаемый результат, но когда я запускаю его напрямую, это дает мне последний обновленный результат.

Вот мой код

int Port { get; set; }
Thread[] tMain= new Thread[4];

 public void btnListen_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 4; i++)
            {
                tMain[i] = new Thread(Connect);
                tMain[i].IsBackground = true;
                tMain[i].Start(8000+i);
            }
        }


 public void Connect(object _port)
        {
            try
            {
                lock ((object)Port)
                {
                    Port = (int)_port;
                }
                IPEndPoint ie = new IPEndPoint(IPAddress.Any, Port);
                Socket listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listenSock.Bind(ie);
                listenSock.Listen(100);
                Thread tListen = new Thread(() => StartListening(listenSock, Port));
                tListen.IsBackground = true;
                tListen.Start();
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

public void StartListening(Socket _socket, int port)
        {
            Socket tempSock,listenerSocket=(Socket)_socket;
            MessageBox.Show("Thread Started"+port.ToString());
            while (true)
            {
                MessageBox.Show("Waiting For Connection");
                tempSock = listenerSocket.Accept();

                Thread tInner = new Thread(ProcessMessages);
                tInner.IsBackground = true;
                tInner.Start(tempSock);
            }
        }

Теперь я вижу вот чтокогда код выполняется, я получаю 8003 во всех окнах сообщений.Это может быть связано с тем, что первые 3 потока не могли изменить свойство в то время, когда к нему обращались.Как получить блокировку в этом случае.

1 Ответ

2 голосов
/ 30 июня 2010

Этот код определенно нуждается в некотором рефакторинге для начала - слишком много потоков, и все в очень узком контексте!

Краткий ответ:

Проблема сводится к тому, что функция Connect вызывается не в те моменты (или даже в порядке), которые вы ожидаете, а только после завершения цикла.

Длинный ответ:

Это довольно типичный сценарий проблем параллелизма при попытке использовать переменные / свойства в пределах экземпляра в функциях. Насколько я могу судить, проблема не получения желаемого значения для Port не имеет прямого отношения к блокировке как таковой. (Это может быть решено таким образом, но не очень изящно и не так, как вы, вероятно, думаете.) В конечном счете, вы не можете контролировать, как блоки времени выделяются различным потокам на уровне процессора, поэтому вы не знаете, какие функции выполняются в каком порядке. Вы также, кажется, смешиваете принципы дизайна с состоянием и без состояния (функциональный), что неизбежно приведет к неприятностям. Придерживайтесь одного - предпочтительно последнего в этом случае - и у вас будет гораздо больше успеха.

Так что я надеюсь, что я буду резок, если скажу, что было бы полезно прочитать немного о многопоточности - это чрезвычайно сложная тема - и попрактиковаться в некоторых общих принципах. Удачи!

...