在应用程序关闭之前,如何确保在单例中处理对象?

时间:2012-01-07 18:23:54

标签: c# singleton watin dispose

我正在使用WatiN进行一些自动化测试,我发现每次测试都创建一个IE实例是不可扩展的。每个IE实例的创建和关闭时间让我活着:

    [TestMethod]
    public void Verify_Some_Useful_Thing()
    {
        using (var browser = new IE())
        {
            browser.GoTo("/someurl");
            // etc..
            // some assert() statements
        }
     }

然而,using语句确实很有用,因为我可以始终确保我的IE实例将调用其dispose()方法来关闭IE窗口。

无论如何,我创建了一个单例,它维护了一个IE实例,我的所有测试都在我的所有测试类中使用:

public class BrowserPool
{      
    private static readonly Lazy<BrowserPool> _instance = new Lazy<BrowserPool>(() => new BrowserPool());        

    private IE _browser;
    private string _ieHwnd;
    private int _threadId;

    public IE Browser
    {
        get
        {
            var currentThreadId = GetCurrentThreadId();
            if (currentThreadId != _threadId)
            {
                _browser = IE.AttachTo<IE>(Find.By("hwnd", _ieHwnd));
                _threadId = currentThreadId;
            }
            return _browser;
        }
        set
        {
            _browser = value;
            _ieHwnd = _browser.hWnd.ToString();
            _threadId = GetCurrentThreadId();
        }
    }

    /// <summary>
    /// private to prevent direct instantiation.
    /// </summary>
    private BrowserPool()
    {
        Browser = new IE();
    }

    /// <summary>
    /// Get the current executing thread's id.
    /// </summary>
    /// <returns>Thread Id.</returns>
    private int GetCurrentThreadId()
    {
        return Thread.CurrentThread.GetHashCode();
    }

    /// <summary>
    /// Accessor for instance
    /// </summary>
    public static BrowserPool Instance
    {
        get
        {
            return _instance;
        }
    }
}

现在进行测试:

  [TestMethod]
  public void Verify_Some_Useful_Thing()
  {
        var browser = BrowserPool.Instance.Browser;
        browser.GoTo("/someurl");
        // some assertions
  }

这很好用,我的测试运行得更快,因为我不是每次测试都打开和关闭IE。但是,我有这个问题,因为当测试完成时我的IE实例仍将保持打开状态。

我无法找到一种优雅的方法来确保BrowserPool.Browser在应用程序结束之前对其调用dispose()或close()。我甚至尝试在BrowserPool类中使用终结器,但这似乎不起作用,因为在调用终结器时已经回收了_browser变量。

如何确保在测试运行后在我的IE实例上调用dispose()?

1 个答案:

答案 0 :(得分:4)

在程序集中找到的测试完成后,使用[AssemblyCleanupAttribute()]清除资源。

顺便说一句,从不依赖于在.NET中使用析构函数。