HiT*_*ech 3 c# using-statement winforms
我得到一个例外"无法访问已处置的对象.".我知道我得到了这个例外,因为在它有机会返回结果之前,该对象已被删除.我想知道的是什么是撤回物体的正确方法.我可能在我的代码中有不必要的步骤,可能这样做错了吗?
所以我在我的主课堂上有一个按钮点击事件.它调用下面代码中显示的方法.GetADComputer方法位于另一个名为ActiveDirectory.cs的类(我创建了一个类文件.cs)中.我在尝试访问被驱散对象的结果时发现了异常.
public static PrincipalSearchResult<Principal> GetADComputer(string pcName)
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
using (ComputerPrincipal computer = new ComputerPrincipal(ctx))
{
computer.Name = String.Format("*{0}*", pcName);
using (PrincipalSearcher searcher = new PrincipalSearcher())
{
searcher.QueryFilter = computer;
return searcher.FindAll();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是DirectoryServices使用Lazy Loading来获取它的信息,所以因为你关闭了上下文,所以你无法再从中检索信息Principal.
您有两个选项,或者将PrincipalContext查询传递给查询,以便在返回时不会超出范围:
public static DoSomthing()
{
using(var ctx = new PrincipalContext(ContextType.Domain))
using(PrincipalSearchResult<Principal> result = GetADComputer("some Name", ctx))
{
//do something with the result here.
}
}
public static PrincipalSearchResult<Principal> GetADComputer(string pcName, PrincipalContext ctx)
{
using (var computer = new ComputerPrincipal(ctx))
{
computer.Name = String.Format("*{0}*", pcName);
using (var searcher = new PrincipalSearcher())
{
searcher.QueryFilter = computer;
return searcher.FindAll();
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您需要将结果转换为不依赖于延迟加载的内容,以便关闭与目录服务器的连接.
public static List<ComputerInfo> GetADComputer(string pcName, PrincipalContext ctx)
{
using (var computer = new ComputerPrincipal(ctx))
{
computer.Name = String.Format("*{0}*", pcName);
using (var searcher = new PrincipalSearcher())
{
searcher.QueryFilter = computer;
using (PrincipalSearchResult<Principal> result = searcher.FindAll())
{
return result.Select(p=> new ComputerInfo(p.Name, p.SID)).ToList();
}
}
}
}
public class ComputerInfo
{
public ComputerInfo(string name, SecurityIdentifier sid)
{
Name = name;
SID = sid;
}
public string Name {get; set;}
public SecurityIdentifier SID {get; set;}
}
Run Code Online (Sandbox Code Playgroud)