昨天我遇到了一個奇怪的問題,這讓我頗爲頭疼。我有一個服務器應用程序與一個服務器類,而這又是從一個連接類派生。 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?等回調時,似乎出現了類似的問題,但這裏的情況有些不同,因爲在我的情況下(我認爲)鎖內的代碼不應發出任何自己試圖獲得鎖的事件物體。