Active Directory提高了C#-WPF中的性能

Active Directory提高了C#-WPF中的性能,c#,wpf,multithreading,performance,active-directory,C#,Wpf,Multithreading,Performance,Active Directory,是否可以借助多线程(Task.Runetc)或任何其他好的技术来提高以下函数的响应时间 UserCollection = new ObservableCollection<User>(); public void FillUserList(string machineName, string groupName) { UserCollection.Clear(); if (string.IsNullOrEmpty(machineName) || string.Is

是否可以借助多线程(
Task.Run
etc)或任何其他好的技术来提高以下函数的响应时间

UserCollection = new ObservableCollection<User>();

public void FillUserList(string machineName, string groupName)
{
    UserCollection.Clear();

    if (string.IsNullOrEmpty(machineName) || string.IsNullOrEmpty(groupName))
        return;

    var machineContext = new PrincipalContext(ContextType.Machine, machineName, null, ContextOptions.Negotiate);
    var group = GroupPrincipal.FindByIdentity(machineContext, groupName);

    var members = group.GetMembers();

    foreach (var member in members)
    {
        var user = new User { DisplayName = member.Name, UserId = member.SamAccountName };
        UserCollection.Add(user);                
    }
}
UserCollection=newobserveCollection();
public void FillUserList(字符串machineName、字符串groupName)
{
UserCollection.Clear();
if(string.IsNullOrEmpty(machineName)| | string.IsNullOrEmpty(groupName))
返回;
var machineContext=new PrincipalContext(ContextType.Machine,machineName,null,ContextOptions.Negotiate);
var group=GroupPrincipal.FindByIdentity(machineContext,groupName);
var members=group.GetMembers();
foreach(成员中的var成员)
{
var user=new user{DisplayName=member.Name,UserId=member.SamAccountName};
UserCollection.Add(用户);
}
}

尝试如下所示处理组和计算机上下文

   group.Dispose(); 
   machineContext.Dispose(); 
这可能有助于提高性能

代码:

    UserCollection = new ObservableCollection<User>();

    public void FillUserList(string machineName,string groupName)
    {
        UserCollection.Clear();
        if (string.IsNullOrEmpty(machineName) || string.IsNullOrEmpty(groupName))
            return;

        var machineContext = new PrincipalContext(ContextType.Machine, machineName, null, ContextOptions.Negotiate);
        var group = GroupPrincipal.FindByIdentity(machineContext, groupName);

        var members = group.GetMembers();

        foreach (var member in members)
        {
            var user = new User { DisplayName = member.Name, UserId = member.SamAccountName };
            UserCollection.Add(user);                
        }

       //try disposing the objects
       group.Dispose(); 
       machineContext.Dispose(); 
    }
UserCollection=newobserveCollection();
public void FillUserList(字符串machineName、字符串groupName)
{
UserCollection.Clear();
if(string.IsNullOrEmpty(machineName)| | string.IsNullOrEmpty(groupName))
返回;
var machineContext=new PrincipalContext(ContextType.Machine,machineName,null,ContextOptions.Negotiate);
var group=GroupPrincipal.FindByIdentity(machineContext,groupName);
var members=group.GetMembers();
foreach(成员中的var成员)
{
var user=new user{DisplayName=member.Name,UserId=member.SamAccountName};
UserCollection.Add(用户);
}
//尝试处理对象
group.Dispose();
machineContext.Dispose();
}
注意:您也可以使用using语句而不是.dispose。参见下面的代码

    UserCollection = new ObservableCollection<User>();

    public void FillUserList(string machineName,string groupName)
    {
        UserCollection.Clear();
        if (string.IsNullOrEmpty(machineName) || string.IsNullOrEmpty(groupName))
            return;

        using(var machineContext = new PrincipalContext(ContextType.Machine, machineName, null, ContextOptions.Negotiate)){

          var group = GroupPrincipal.FindByIdentity(machineContext, groupName);

          var members = group.GetMembers();

          foreach (var member in members)
          {
             var user = new User { DisplayName = member.Name, UserId = member.SamAccountName };
             UserCollection.Add(user);                
          }

         //try disposing the objects
         group.Dispose(); 
       }
    }
UserCollection=newobserveCollection();
public void FillUserList(字符串machineName、字符串groupName)
{
UserCollection.Clear();
if(string.IsNullOrEmpty(machineName)| | string.IsNullOrEmpty(groupName))
返回;
使用(var machineContext=new PrincipalContext(ContextType.Machine,machineName,null,ContextOptions.congregate)){
var group=GroupPrincipal.FindByIdentity(machineContext,groupName);
var members=group.GetMembers();
foreach(成员中的var成员)
{
var user=new user{DisplayName=member.Name,UserId=member.SamAccountName};
UserCollection.Add(用户);
}
//尝试处理对象
group.Dispose();
}
}

正如其他人已经注意到的那样,代码非常简单,实际上不可能在多个线程中运行(如果我弄错了,请告诉我)。虽然可能会稍微提高您的方法的响应时间,但不幸的是,我认为它不会非常快

有时候,事情就像是在享受他们的甜蜜时光,作为开发人员,我们必须接受它,并欺骗用户,让他们认为他们根本没有等待

所以,我的建议是:

    UserCollection = new ObservableCollection<User>();

    public void FillUserList(string machineName,string groupName)
    {
        UserCollection.Clear();
        if (string.IsNullOrEmpty(machineName) || string.IsNullOrEmpty(groupName))
            return;

        var machineContext = new PrincipalContext(ContextType.Machine, machineName, null, ContextOptions.Negotiate);
        var group = GroupPrincipal.FindByIdentity(machineContext, groupName);

        var members = group.GetMembers();

        foreach (var member in members)
        {
            var user = new User { DisplayName = member.Name, UserId = member.SamAccountName };
            UserCollection.Add(user);                
        }

       //try disposing the objects
       group.Dispose(); 
       machineContext.Dispose(); 
    }
您正在同一线程中同步运行此方法(
FillUserList
),该线程用于处理事件并执行与GUI相关的所有其他操作(UI线程)。这使得应用程序在方法忙于加载用户时“冻结”。通常,当您无法避免较长的加载时间时,您会将繁重的任务重定向到后台(后台线程,甚至是同一个线程,但异步运行),同时保持UI完全响应

我使用与您当前场景非常相似的方法准备了一个示例解决方案。唯一的区别是我使用的是控制台应用程序,而不是WPF。但是,您应该能够轻松地修改我的代码以在您的场景中工作

class Program
{
    static List<string> UserCollection = null;

    static void Main(string[] args)
    {
        FillUserList("Hello", "World");
        Console.ReadLine();
    }

    public static void FillUserList(string machineName, string groupName)
    {
        var worker = new BackgroundWorker();
        var temporaryUserCollection = new List<string>();

        worker.DoWork += (s, ea) => { YourLongRunningTask(machineName, groupName, temporaryUserCollection); };
        worker.RunWorkerCompleted += (s, ea) => { UserCollection = temporaryUserCollection; Console.WriteLine("Loaded."); };
        worker.RunWorkerAsync();

        // I'm writing to the console, but you should show
        // some sort of loading indicator (spinner, "please wait" dialog, progress bar, etc.) in this line
        Console.WriteLine("Loading...");
    }

    public static void YourLongRunningTask(string machineName, string groupName, List<string> userCollection)
    {
        // Paste your current FillUserList code here
        Thread.Sleep(5000);
        userCollection.Add("A");
        userCollection.Add("B");
        userCollection.Add("C");
    }
}
类程序
{
静态列表UserCollection=null;
静态void Main(字符串[]参数)
{
FillUserList(“你好”,“世界”);
Console.ReadLine();
}
公共静态void FillUserList(字符串machineName、字符串groupName)
{
var worker=新的BackgroundWorker();
var temporaryUserCollection=新列表();
worker.DoWork+=(s,ea)=>{YourLongRunningTask(machineName,groupName,temporaryUserCollection);};
worker.RunWorkerCompleted+=(s,ea)=>{UserCollection=temporaryUserCollection;Console.WriteLine(“已加载”);};
worker.RunWorkerAsync();
//我正在给控制台写信,但你应该给我看看
//该行中有某种加载指示器(微调器、“请等待”对话框、进度条等)
控制台。写入线(“加载…”);
}
公共静态void YourLongRunningTask(字符串machineName、字符串groupName、列表userCollection)
{
//将当前的FillUserList代码粘贴到此处
睡眠(5000);
userCollection.Add(“A”);
userCollection.Add(“B”);
userCollection.Add(“C”);
}
}

您看到的是缓慢吗?关于此方法的性能,您目前的经验是什么?是的,随着组中用户数量的增加,性能越来越差。如果任何组有2个用户(5秒)7个用户(12-14秒)要回复!代码看起来很简单我能想到的唯一一件事是网络问题,即延迟问题,或者在分配成员变量后,尝试在方法中设置machineContext=null,并放置
UserCollection
对象,除非您没有显示该对象的全部范围,否则我不知道该对象的显示频率正在调用FillUserList。基本上,我已经创建了WPF应用程序,它有两个文本框。用户正在提供machinename和groupname。在输入groupname之后,在expander的帮助下,我将显示与相应组关联的用户(两个标签)