有没有更快的方法来检索 System.Environment.UserName?
Posted
技术标签:
【中文标题】有没有更快的方法来检索 System.Environment.UserName?【英文标题】:Is there a faster way to retrieve System.Environment.UserName? 【发布时间】:2011-03-22 17:40:31 【问题描述】:System.Environment.UserName 内部调用
[DllImport("advapi32.dll", CharSet=CharSet.Auto)] internal static extern bool GetUserName(StringBuilder lpBuffer, ref int nSize);
每次调用似乎都会命中 AD,因此网络延迟和 AD 查询会影响执行速度。
您是否知道是否有更好的方法来检索此值?
可能是线程某处的缓存 SID 之类的东西? 所以我可以读取用户名和 SID 并在本地缓存它们(在执行时),并且只有在获得新的 SID(或类似的东西)时才查询 System.Environment.UserName。
谢谢,
【问题讨论】:
只是一个想法,也许有一种方法可以强制 Windows 服务器将 AD 的结果缓存一段时间? 也许我遗漏了一些明显的东西,但是为什么您在检索一次用户名后不自己缓存它们? 单例的诅咒 :( 用户名被放入每个日志条目中,其中我只有一个记录器实例在线程之间共享/在远程调用(模拟)等期间使用...... 【参考方案1】:检索用户的 WindowsIdentity。 Name 属性检索 Domain\Name 和 User.Value SID。
System.Security.Principal.WindowsIdentity.GetCurrent()
【讨论】:
这个比较慢,需要创建WindowsIdentity,在内部调用KerbS4ULogon,在WinAPI的LSA区域的其他几次调用以LsaLogonUser结束。绝对重 - 我正在寻找本地某处缓存的东西。【参考方案2】:我不知道这是否符合您的需求,但也许:
System.Environment.GetEnvironmentVariable("username");
【讨论】:
您知道 System.Environment.UserName 是做什么的,不是吗? :-) @stic:我知道它的用途。您能否详细说明您对System.Environment.UserName
的替代方案的特殊要求?
我认为 stic 暗示 System.Environment.UserName
实际上调用了 GetEnvironmentVariable
(但我不知道——我对 .NET 一无所知......)。
安德烈亚斯,你说得对,这两个在大多数(稍微复杂一点的)情况下会给出不同的结果。弗兰克 - 对于您关心阅读此值(您期望它会改变)的情况,阅读环境是毫无意义的。否则,我会读一次并存储在局部变量或类似的东西中
@stic:我明白你的意思,但你的问题并不完全清楚。 @Andreas:System.Environment.UserName
绝对不是基于环境变量的。环境变量在程序启动时初始化一次。但正如您从 stics 问题中看到的那样,System.Environment.UserName
在运行时通过 Win32 API 调用解决。【参考方案3】:
下面的代码似乎可以解决问题。
如果尚未设置,首先获取线程上的当前主体。 每次下一次就用它,给线程本身增加一点开销,但不会每次都调用AD。
有什么想法吗?
if (!System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated )
System.Threading.Thread.CurrentPrincipal =
new System.Security.Principal.WindowsPrincipal(
System.Security.Principal.WindowsIdentity.GetCurrent());
userName = System.Threading.Thread.CurrentPrincipal.Identity.Name;
【讨论】:
以上是关于有没有更快的方法来检索 System.Environment.UserName?的主要内容,如果未能解决你的问题,请参考以下文章