2009-11-17 7 views
1

я следующее:Threading и розетки

ThreadStart startThread = 
    delegate 
    { 
      mySocket.StartListen(); 
    }; 

mySocket теперь зацикливание на Listen(), когда я:

new Thread(startThread).Start(); 

Вот StartListen:

public void StartListen() 
{ 
Object locker = new Object(); 

// Lock resources 
lock (locker) 
{ 
    S = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, 
     System.Net.Sockets.SocketType.Stream, 
     System.Net.Sockets.ProtocolType.Tcp); 
    S.Blocking = false; 

    try 
    { 
    S.Bind(serverEP); 
    S.Listen(1000); 
    isListening = true; 

    /* 
    * While statement not required here because AcceptConnection() 
    * method instructs the socket to BeginAccept() again... 
    */ 
    //while (true) 
    //{ 
    connectDone.Reset(); 
    S.BeginAccept(new AsyncCallback(AcceptConnection), Channel); 
    connectDone.WaitOne(); 
    //} 
    } 
    catch (System.Net.Sockets.SocketException SockEx) 
    { 
    Console.WriteLine("*****[" + name + "] " + SockEx.SocketErrorCode + ":"); 
    Console.WriteLine("*****[" + name + "] " + SockEx.Message); 
    } 
} 
} 

Из-за асинхронные методы не действительно «завершают» и возвращают сигнал для чего-либо еще. Любые команды, которые я реализую после того, как Thread.Start() выше, работают некорректно. Например, в StartListen, обратите внимание, что у меня есть isListening = true. После запуска потока я хочу использовать свойство IsListening. Он всегда возвращается как ложный.

Как мне начать тему. Был бы предпочтительным асинхронный метод (т. Е. ThreadStart.BeginInvoke())? Разве это не похоже на использование ManualResetEvent?

ответ

2

Mark isListening как volatile. Насколько я понимаю, вы ссылаетесь на этот флаг в двух разных потоках. Обычно данные, разделяемые между потоками, должны быть синхронизированы, но, похоже, вы этого не делаете. Однако, учитывая, что флаг является типом bool, вам технически не требуется синхронизировать доступ к нему, потому что платформа .NET гарантирует, что чтение и запись из типов bool являются атомарными (I думаю Я говорю это правильно .. кто-то, пожалуйста, исправьте меня, если это не технически правильно). Но, чтобы убедиться, что данные этого типа действительно получают самое последнее значение, вам нужно отметить его как volatile.

Кроме того, вам будет лучше использовать класс TcpListener вместо того, чтобы пытаться сделать это с помощью класса Socket. То, что вы делаете, не так, но класс TcpListener сделает ваш код более простым для чтения и обслуживания, ИМО.

И наконец, объект locker, который вы используете, на самом деле ничего не делает, поскольку он является локальным для метода StartListen(). Чтобы объекты синхронизации имели какой-либо эффект, они должны быть доступны для потоков, которым необходим последовательный доступ к общим данным. Как вы это делаете, другие потоки не могут получить доступ к переменной locker, что делает ее бесполезной.

+0

Я раньше не использовал «volatile». Я прочитаю об этом. Использование TcpListener не может быть полностью исключено. Тем не менее, у меня уже есть все асинхронные операции, написанные и работающие с классом Sockets. Я решил работать с базовым классом, вместо того, чтобы легко выходить на TcpListener/TcpClient. :) – IAbstract

+0

Использование класса 'Socket' не является ошибкой. Просто «TcpListener» намного проще, поскольку он был специально разработан для того, как вы используете «Socket». –

Смежные вопросы