具有一次性参数的背景工作者

本文关键字:背景 工作者 参数 一次性 | 更新日期: 2023-09-27 18:36:53

>我有一个后台工作者接收一次性对象作为参数。 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]);
                }
            }
        }
    }

具有一次性参数的背景工作者

对象肯定是在 using 块的末尾释放的,因此您的后台工作线程正在使用已释放的实例。

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