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的帮助下,我将显示与相应组关联的用户(两个标签)