BackgroundWorker 忽略模拟
Posted
技术标签:
【中文标题】BackgroundWorker 忽略模拟【英文标题】:BackgroundWorker ignores Impersonation 【发布时间】:2015-12-29 10:34:35 【问题描述】:在我的 C# 应用程序中,我使用Impersonation
来扩展用户的访问权限。为方便起见,我只是添加了一个public static Impersonation
对象,该对象在App启动时初始化。
Impersonation
的代码来自this answer on ***。
到目前为止,在应用程序中执行任何代码都可以正常工作:
someCodeThatNeedsImpersonation(); // Fine
somethingElse();
我现在想将代码移动到BackgroundWorker
:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, a) =>
someCodeThatNeedsImpersonation(); // fails to "see" impersonation
bw.RunWorkerCompleted += (s, a) =>
somethingElse();
bw.RunWorkerAsync();
这失败了,因为显然在主线程中初始化的Impersonation
句柄没有在BackgroundWorker
中使用。
当然,快速解决方法是
bw.DoWork += (s, a) =>
using ( new Impersonation(...) )
someCodeThatNeedsImpersonation(); // works, because of bw's own impersonation
但我更喜欢在每个 BackgroundWorker 中都不需要新的模拟句柄的解决方案(因为我肯定会忘记一个)。有没有办法共享主线程的static Impersonation
对象?
【问题讨论】:
这个是关于ASP.NET的,但是原因和解决方法都是一样的:blogs.msdn.com/b/tom/archive/2008/04/22/… 这也可能有帮助:blog.iamandycohen.com/2012/09/17/… @Dennis 感谢您的链接。第一个链接 (blogs.msdn.com/b/tom/archive/2008/04/22/…) 的方法 2 完美运行。您想将此作为答案发布吗? 好吧,我的答案没有投资,所以,请随意发布答案。此外,它所说的问题是广泛讨论的基础——因为这是桌面应用程序(我假设它是使用BackgroundWorker
),这是一个大问题,为什么你需要这么多地方来模拟。所以,你接受的解决方案对我来说看起来不太好,因为,IMO,它隐藏了真正的设计问题。
【参考方案1】:
在 Windows 中,模拟令牌是为每个线程单独维护的,并且在您创建新线程时不会被继承。
要走的路是只模拟需要它的代码路径,正如您已经在 using(...)
中展示的那样。我想说,唯一的区别是,我不会发出.DoWork += new Impersonation(...)
,而是这样做:
var bw = new BackgroundWorker();
bw.DoWork += Impersonated(TOKEN, (s, a) => /* code */ );
考虑到BackgroundWorker
没有密封,并且它的OnDoWork()
方法受到保护,另一种方法是继承类并覆盖OnDoWork()
来模拟。然后,你可以这样做:
var bw = new ImpersonatingBackgroundWorker(...)
【讨论】:
我完全同意“仅在您需要的地方进行模拟”,但这就是项目发展的方式.. 是的,你可以使用更长的模拟,但仍然可以减少重复,就像我的例子一样。注意到BackgroundWorker
不是密封类,并且OnDoWork()
受到保护,您可以做的另一件事是继承和覆盖OnDoWork()
以模拟。然后就做var bw = new ImpersonatingBackgroundWorker(...)
。但我个人更喜欢我给出的示例——没有继承——更好。【参考方案2】:
如blogs.msdn.com 所述,将以下sn-p 添加到App.config
文件足以使Impersonation
跨越线程边界。
<configuration>
<runtime>
<alwaysFlowImpersonationPolicy enabled="true"/>
<legacyImpersonationPolicy enabled="false"/>
</runtime>
</configuration>
但是,最佳实践解决方案只会在实际需要的地方使用模拟,而不是在全局范围内使用。
【讨论】:
以上是关于BackgroundWorker 忽略模拟的主要内容,如果未能解决你的问题,请参考以下文章
Android Webview Back按钮适用于模拟器,但不适用于设备
C# form发起backgroundworker 当form close时 backgroundworker 还会继续工作吗