我有以下内容:
ThreadStart startThread =
delegate
{
mySocket.StartListen();
};
当my:时,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?
答案 0 :(得分:2)
将isListening
标记为volatile
。据我了解,你在两个不同的线程中引用了这个标志。通常情况下,线程之间共享的数据必须同步,但看起来你并没有这样做。但是,鉴于该标志是bool类型,您在技术上不必同步对它的访问,因为.NET框架保证bool类型的读取和写入是原子的(我认为我是说的正确......有人请纠正我,如果它在技术上不正确)。但是,为了确保该类型的读取实际上获得最新值,您需要将其标记为volatile
。
此外,您最好使用TcpListener
类,而不是尝试使用Socket
类。你所做的并没有错,但是TcpListener
类会使你的代码更容易阅读和维护,IMO。
最后,您使用的locker
对象并没有真正做任何事情,因为它是StartListen()
方法的本地对象。为了使同步对象具有任何效果,需要对需要序列化访问共享数据的线程访问它们。你在这里做的方式,其他线程无法访问locker
变量,从而使它变得无用。