昨天我遇到了一个奇怪的问题,这让我颇为头疼。我有一个服务器应用程序与一个服务器类,而这又是从一个连接类派生。 Connection类提供有关连接状态和可能性的信息,收于实际发送数据锁定专用锁对象导致死锁
private void ConnectAndPollForData()
{
try
{
TcpListener listener = new TcpListener(Port);
listener.Start();
while (true)
{
connection = listener.AcceptSocket();
string currentBuffr = string.Empty;
const int READ_BUFFER_SIZE = 1024;
byte[] readBuffr = new byte[READ_BUFFER_SIZE];
while (Connected)
{
int bytesReceived;
lock (lockObject)
{
bytesReceived = connection.Receive(readBuffr, READ_BUFFER_SIZE, SocketFlags.None);
}
currentBuffr += ASCIIEncoding.ASCII.GetString(readBuffr, 0, bytesReceived);
//do stuff
}
}
catch(ThreadAbortException)
{
Thread.ResetAbort();
}
finally
{
}
}
public void SendString(string stringToSend)
{
stringToSend += "\r\n";
if(Connected)
{
lock(lockObject)
{
connection.Send(ASCIIEncoding.UTF7.GetBytes(stringToSend));
}
}
}
还有就是连接对象没有其他明确的接入连接
public bool Connected
{
get
{
if (connection != null)
{
lock (lockObject)
{
bool blockingState = connection.Blocking;
try
{
connection.Blocking = false;
connection.Send(new byte[1], 1, 0);
}
catch (SocketException e)
{
if (!e.NativeErrorCode.Equals(10035))
{
return false;
}
//is connected, but would block
}
finally
{
connection.Blocking = blockingState;
}
return connection.Connected;
}
}
return false;
}
}
public virtual void CloseConnection()
{
if (Connected)
{
lock (lockObject)
{
connection.Close();
}
}
}
服务器类是resonsible。 ConnectAndPollForData函数在单独的线程中执行。每当我运行这个版本的主机(我目前使用的是非线程安全的版本,这会导致其他问题),它会在通过TCP接收到很多行之后挂起。暂停调试器向我显示,一个线程尝试使用Connected的锁执行代码,而另一个尝试在ConnectAndPollForData的锁中接收数据。这种行为对我来说似乎很奇怪,因为我期望在第一个锁内执行代码,然后执行第二个锁。在使用Deadlocking lock() method或'Deadlock' with only one locked object?等回调时,似乎出现了类似的问题,但这里的情况有些不同,因为在我的情况下(我认为)锁内的代码不应发出任何自己试图获得锁的事件物体。