Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有一次性参数的后台工作程序_C#_.net - Fatal编程技术网

C# 具有一次性参数的后台工作程序

C# 具有一次性参数的后台工作程序,c#,.net,C#,.net,我有一个后台工作程序,它接收一个一次性对象作为参数。在using块内调用RunWorkerAsync方法 下面是一个简化的代码示例 private void SearchTest(string filter) { bgWorker.DoWork += bgWorker_DoWork; using (DirectoryEntry dirEntry = new DirectoryEntry()) { using

我有一个后台工作程序,它接收一个一次性对象作为参数。在using块内调用
RunWorkerAsync
方法

下面是一个简化的代码示例

    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块的末尾被释放的,因此您的后台工作程序正在使用一个已释放的实例


我猜测为什么它仍然有效是因为
DirectorySearcher
只有一个
Dispose
方法,因为它派生自
组件
,实际上没有使用它,也就是说,
Dispose
不做任何事情,这个类的方法也不关心Dispose是否被调用。

这看起来肯定会失败,
ObjectDisposedException
…您不能在这里使用using语句,对象将在线程运行之前或运行时被释放。卡布姆。您需要在DoWork事件处理程序或RunWorkerCompleted事件处理程序中处理它。@HansPassant:我认为在这种特定情况下没有kaboom,请参阅我的答案。@Hans Passant我知道这看起来很奇怪,但这段代码正在工作。@Guish它是靠运气工作的。未来版本的.Net可能会开始抛出一个
ObjectDisposedException
,因此一定要使用
移动到worker。我查看了
FindAll()
的代码,它没有检查对象是否已被释放,这可能解释了为什么它没有抛出异常。看起来很不安全,在未来的版本中可能会中断。@Matthew Watson:我想改为在后台工作程序完成时执行dispose。它使用dispose(),下面有一个Marshal.ReleaseComObject()调用。@Daniel Higarth dispose方法实际上调用了基组件
dispose
methodYeah,我现在也看了一下代码:它做了一些事情,但显然没有影响OP使用的方法的功能。
    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]);
                }
            }
        }
    }