线程和套接字
我有以下内容:
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。 它总是返回false。
我应该如何启动线程。 异步方法(即ThreadStart.BeginInvoke())是否可以优先使用? 是不是类似于使用ManualResetEvent?
Mark isListening
as volatile
。 据我了解,你在两个不同的线程中引用这个标志。 通常情况下,线程之间共享的数据必须同步,但看起来你并没有这样做。 但是,鉴于该标志是bool类型,您在技术上不必同步对它的访问,因为.NET框架保证bool类型的读取和写入是primefaces的(我想我说的正确…某人请纠正我,如果它在技术上不正确)。 但是,为了确保从该类型读取实际获得最新值,您需要将其标记为volatile
。
此外,您最好使用TcpListener
类,而不是尝试使用Socket
类。 你正在做的事情没有错,但是TcpListener
类会使你的代码更容易阅读和维护,IMO。
最后,你正在使用的locker
对象并没有真正做任何事情,因为它是StartListen()
方法的本地StartListen()
。 为了使同步对象具有任何效果,需要对需要序列化访问共享数据的线程访问它们。 你在这里的方式,其他线程无法访问locker
变量,从而使它无用。