Потоки и их взаимодействие с параллельным словарем и sw.Flush();

Рассмотрим этот код:

class program
{
    public static ConcurrentDictionary<string, int> dictionary = new ConcurrentDictionary<string,int>();

    static void Main(string[] args)
    {
        runServer();
    }

    static void runServer()
    {
        //Server setup

        Handler threadRequest;  
        Thread[] threadsArray = new Thread[2];
        int i = 0;

        while(true)
        {
            Socket connection;
            connection = listener.AcceptSocket();

            threadRequest = new Hander();

            threadsArray[i] = new Thread(() => threadRequest.clientInteraction(connection, dictionary));

            threadsArray[i].Start();
            i++;
        }       

    }
}

class Handler
{
    public void clientInteraction(Socket connection, ConcurrentDictionary<string, int> dictionary)
    {
        NetworkStream socketStream;

        socketStream = new NetworkStream(connection);   

        StreamWriter sw = new StreamWriter(socketStream);
                StreamReader sr = new StreamReader(socketStream);

        parseStrings(out pTeamName); //checks to see if its a valid "add team" request

        dictionary.tryAdd(pTeamName, 0);

        while(dictionary.Count < 2)
        {
            //hang until two teams
        }

        sw.WriteLine("Welcome To The Game.");
        sw.Flush();

        foreach(KeyValuePair<string, int> kvp in dictionary)
                {
                    Console.WriteLine("Team: {0}", kvp.Key);
                }



                foreach(KeyValuePair<string, int> kvp in dictionary)
                {
                    sw.WriteLine("Team: {0}", kvp.Key);
                    sw.Flush();
                }
    }


}

Эта программа принимает два клиентских соединения как разные потоки и запускает метод clientInteraction в классе обработчика для каждого потока. Меня беспокоит то, что если два потока одновременно попадут в sw.Flush(), сервер не сможет его выполнить.

Я полагаю, что это так, поскольку сервер не печатает «Добро пожаловать в игру» ни одному из клиентов, а печатает только одну запись dictionary (одна и та же запись) для обоих клиентов и пропускает одну.

От отладки и Console.WriteLine до просто консоли сервера я знаю, что словарь заполнен правильно. Я просто не понимаю, почему письмо клиентам не работает.

Любая помощь приветствуется, и если я пропустил что-то важное, дайте мне знать. Заранее спасибо.

РЕДАКТИРОВАТЬ: Кажется, что по какой-то причине любой «другой» набор флешей работает. Я например поставил:

 while(true)
 {
     sw.WriteLine("BOO");
     sw.Flush();
     Console.ReadKey();
  }

Прямо под циклом foreach для печати словаря клиентам. Первые два ReadKeys выводят "BOO" одному из клиентов (в зависимости от того, какой поток первый), затем два следующих ничего не делают. Следующие два, однако, снова печатают «BOO». Я не особенно хочу обрамлять каждый sw.Flush() циклом i=2 for только для того, чтобы заставить его работать.


person James    schedule 28.03.2016    source источник
comment
Похоже, у вас есть бесконечный цикл в цикле while(true), потому что я не вижу break или return.   -  person Quantic    schedule 28.03.2016
comment
@Quantic Это сервер; это то, что вы ожидаете, по крайней мере, от примитивного сервера.   -  person Servy    schedule 28.03.2016
comment
@Servy Хорошо, плохо. Я предполагаю, что единственная проблема заключается в том, что threads[2] не существует, поэтому он просто рухнет после того, как i++ запустится во второй раз. Я дойду до двери, иначе у меня не будет много полезного.   -  person Quantic    schedule 28.03.2016
comment
@Quantic Да, вы правы, это прерывается после принятия второго соединения.   -  person Servy    schedule 28.03.2016
comment
Если я когда-либо планирую иметь только 2 подключения, это будет проблемой? Очевидно, что это может быть нарушено, если я попытаюсь подключиться снова, но не будет ли оно просто прослушивать третье соединение, которое никогда не приходит, пока я делаю то, что мне нужно, в методе clientInteraction?   -  person James    schedule 28.03.2016
comment
@James Если вы хотите, чтобы сервер выключился после принятия второго соединения, выключите сервер после принятия второго соединения.   -  person Servy    schedule 28.03.2016


Ответы (1)


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

person Servy    schedule 28.03.2016
comment
Хорошо, если я оставлю все проблемы с параллелизмом на усмотрение ОС, я не понимаю, почему мои стримеры не работают. - person James; 28.03.2016