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

时间:2015-06-26 20:34:18

标签: c# wpf multithreading performance active-directory

是否可以借助多线程(Task.Run等)或任何其他好的技术来改善以下功能的响应时间?

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);                
    }
}

2 个答案:

答案 0 :(得分:1)

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

有时候事情只是为了享受他们的美好时光,而作为开发者我们只需要接受它并诱骗用户认为他们根本不在等待。

所以,这是我的建议:

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

我使用与您当前情景非常相似的BackgroundWorker准备了一个示例解决方案。唯一的区别是我使用的是控制台应用程序,而不是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");
    }
}

答案 1 :(得分:0)

尝试处理组和机器上下文,如下所示,

   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(); 
    }

注意:您也可以使用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(); 
       }
    }