我正在使用一些代码(不是我的,我急于添加,我不太相信这些),它会打开一个套接字,发出请求并侦听响应,这会引发异常当我在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