NUnit使tcp连接保持活动状态

时间:2013-11-28 14:57:32

标签: c# tcp nunit

使用TcpListener的简单类(这只是为了解决问题,绝不会让这个类有任何实际意义):

using System;
using System.Net.Sockets;

namespace NUnitTcp
{
    public class Foo
    {
        TcpListener lst;

        public Foo()
        {
            lst = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 9090);
        }

        ~Foo()
        {
            lst.Stop();
        }

        public void Start()
        {
            lst.Start();
        }

        public void Stop()
        {
            lst.Stop();
        }

    }
}

使用Foo的简单应用程序:

using System;

namespace NUnitTcp
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo();
            f.Start();
        }
    }
}

此应用程序运行正常,应用程序结束后即可释放端口,并且应用程序可以再次运行!即使没有Foo中的析构函数,这仍然会发生!

使用Foo进行简单的NUnit测试:

using System;
using NUnitTcp;
using NUnit.Framework;

namespace NUnitTcpTests
{
    [TestFixture]
    public class TcpTests
    {
        [Test]
        public void test1()
        {
            Foo f = new Foo();
            f.Start();

            Assert.True(true);
        }
    }
}

此测试将在NUnit GUI中运行一次。该测试的任何后续执行都将抛出异常,通知我们该端口正在使用中。 NUnit GUI重启将释放端口 你认为这是一个错误吗?对我来说就像一个......

更正 - 测试将随机抛出异常,对我来说大约有70%的时间。

2 个答案:

答案 0 :(得分:5)

垃圾收集器是不确定的。它仅在第一个示例中立即关闭,因为该进程退出。我强烈建议您实施IDisposable而不是使用终结器,然后您可以使用:

using(Foo f = new Foo())
{
    f.Start();
    Assert.True(true);
}

安全地知道它会立即关闭。

有类似的东西:

public void Dispose()
{
    if(lst != null) lst.Stop();
    lst = null;
}

答案 1 :(得分:2)

端口正在使用,直到垃圾收集器不会收集您的Foo实例。因此你定义了终结器,它将需要两个垃圾收集来调用终结器(Foo将在第一次垃圾收集期间移动到终结队列,终结器将在第二次调用期间可能垃圾收集)。如果您想确保端口将被释放,我建议您在Foo方法中手动关闭停止TearDown

private Foo _foo;

[SetUp]
public void Setup()
{
    _foo = new Foo();;
}

[Test]
public void test1()
{
    _foo.Start();
    // Assert 
}

[TearDown]
public void TearDown()
{
    if (_foo != null)
      _foo.Stop();
}

同样在IDisposable类上实现Foo会很好,因为它使用了非托管资源,应该将其释放:

public class Foo : IDisposable
{
    TcpListener lst;

    public Foo()
    {
        lst = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 9090);
    }

    public void Dispose()
    {
        lst.Stop();
    }
}