我正在使用一些代碼(不是我的,我急於添加,我不太相信這些),它會打開一個套接字,發出請求並偵聽響應,這會引發異常當我在xunit中測試時我無法理解。我假設發生同樣的異常「活」,但類是由單身人士引用,因此它可能只是隱藏。處理socket/finalizing兩次的問題?
該問題在xunit中顯示爲「System.CannotUnloadAppDomainException:卸載appdomain時出錯」,內部異常是在關閉套接字時拋出(基本上)在終結器中的「System.ObjectDisposedException」!沒有其他引用關於調用close和socket的套接字在Socket類中受到保護,所以我不清楚該對象可以如何處置。此外,如果我只是捕獲並吸收ObjectDisposedException,xunit在命中關閉偵聽器線程時會終止。
我只是不明白Socket在被要求關閉之前如何處置。
我的套接字知識只是我發現這個問題後所學到的,所以我不知道我是否提供了可能需要的一切。 LMK如果不是!
public class Foo
{
private Socket sock = null;
private Thread tListenerThread = null
private bool bInitialised;
private Object InitLock = null;
private Object DeInitLock = null;
public Foo()
{
bInitialised = false;
InitLock = new Object();
DeInitLock = new Object();
}
public bool initialise()
{
if (null == InitLock)
return false;
lock (InitLock)
{
if (bInitialised)
return false;
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 8);
sock.Bind(/*localIpEndPoint*/);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(mcIP));
tListenerThread = new Thread(new ThreadStart(listener));
tListenerThread.Start();
bInitialised = true;
return true;
}
}
~Foo()
{
if (bInitialised)
deInitialise();
}
private void deInitialise()
{
if (null == DeInitLock)
return;
lock (DeInitLock)
{
if (bInitialised)
{
sock.Shutdown(SocketShutdown.Both); //throws System.ObjectDisposedException
sock.Close();
tListenerThread.Abort(); //terminates xunit test!
tListenerThread = null;
sock = null;
bInitialised = false;
}
}
}
}
感謝您的。鑑於該類是在一個預計會持續項目生命週期的單例中引用的,finaliser *在關閉時(通過IIS或xunit的拆卸)正在運行 - 如果GC將拾取套接字和線程,則此類需要根本無法解決問題? – annakata 2009-01-08 10:55:22
(應該說應用程序實例的生命週期,而不是項目) – annakata 2009-01-08 10:56:01