3

我有一个后台工作人员接收一次性对象作为参数。该RunWorkerAsync方法在 using 块内调用。

这是一个简化的代码示例

    private void SearchTest(string filter)
    {
        bgWorker.DoWork += bgWorker_DoWork;
        using (DirectoryEntry dirEntry = new DirectoryEntry())
        {
            using (var search = new DirectorySearcher(dirEntry))
            {
                search.SearchScope = SearchScope.Subtree;
                search.Filter = string.Format("(&(objectCategory=group)(cn={0}))", filter);
                bgWorker.RunWorkerAsync(search);
            }
        }
    }
    void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        var searcher = (DirectorySearcher) e.Argument;
        var reportList = new List<String>();

        bgWorker.ReportProgress(0);

        SearchResultCollection results = searcher.FindAll();
        foreach (SearchResult result in results)
        {
            reportList.Add(result.Properties["cn"][0]);

            bgWorker.ReportProgress(1);
        }
        e.Result= reportList;

    }

此代码正在工作(即:参数未在 using 块的末尾处理,后台工作人员正在工作,而 using 块的末尾被击中),但我无法弄清楚 using 块是如何工作的在这种情况下。后台工作者参数是否被克隆并且不会被正确处理,该Dispose方法是否会在后台工作者完成时被调用?发生了什么?

编辑:我删除了后台工作人员并在丹尼尔回答后处置了该对象,它仍然有效......所以这确实是一个DirectorySearcher Dispose特殊性......:

    private void SearchTest(string filter)
    {
        bgWorker.DoWork += bgWorker_DoWork;
        using (DirectoryEntry dirEntry = new DirectoryEntry())
        {
            using (var search = new DirectorySearcher(dirEntry))
            {
                search.SearchScope = SearchScope.Subtree;
                search.Filter = string.Format("(&(objectCategory=group)(cn={0}))", filter);

                ////////////////////
                search.Dispose();
                ////////////////////

                var reportList = new List<String>();
                SearchResultCollection results = searcher.FindAll();//Still work with the disposed instance
                foreach (SearchResult result in results)
                {
                    reportList.Add(result.Properties["cn"][0]);
                }
            }
        }
    }
4

1 回答 1

3

该对象肯定在 using 块的末尾被释放,因此您的后台工作人员正在使用已释放的实例。

我对它为什么仍然有效的猜测是它DirectorySearcher只有一个Dispose方法,因为它派生自它Component并且实际上并没有使用它,即Dispose不做任何事情,并且此类的方法不关心是否已调用 Dispose或不。

于 2013-10-24T13:10:00.207 回答