是否可以借助多线程(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);
}
}
答案 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();
}
}