C# BackgroundWorker忽略模拟

C# BackgroundWorker忽略模拟,c#,windows,backgroundworker,impersonation,C#,Windows,Backgroundworker,Impersonation,在我的C#应用程序中,我使用模拟来扩展用户的访问权限。为了方便起见,我刚刚添加了一个公共静态模拟对象,该对象在应用程序启动时初始化 模拟的代码来自。 到目前为止,在应用程序中执行任何代码都可以正常工作: someCodeThatNeedsImpersonation(); // Fine somethingElse(); 我现在想将代码移动到后台工作程序中: BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (s, a) =&g

在我的C#应用程序中,我使用
模拟
来扩展用户的访问权限。为了方便起见,我刚刚添加了一个
公共静态模拟
对象,该对象在应用程序启动时初始化

模拟的代码来自。
到目前为止,在应用程序中执行任何代码都可以正常工作:

someCodeThatNeedsImpersonation(); // Fine
somethingElse();
我现在想将代码移动到
后台工作程序中

BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, a) =>
{
    someCodeThatNeedsImpersonation(); // fails to "see" impersonation
}
bw.RunWorkerCompleted += (s, a) =>
{
    somethingElse();
}
bw.RunWorkerAsync();
这会失败,因为在主线程中初始化的
模拟
句柄显然没有在
BackgroundWorker
中使用

当然,一个快速解决办法是

bw.DoWork += (s, a) =>
{
    using ( new Impersonation(...) )
    {
        someCodeThatNeedsImpersonation(); // works, because of bw's own impersonation
    }
}

但我更喜欢一个解决方案,它不需要在每个BackgroundWorker中都使用新的模拟句柄(因为我肯定会忘记一个)。是否有方法共享主线程的
静态模拟
对象?

在Windows中,模拟令牌分别为每个线程维护,并且在创建新线程时不会继承

方法是只模拟需要它的代码路径,正如您使用(…)
所示。我想说的唯一区别是,我不会发出
.DoWork+={new Impersonation(…)}
,而是这样做:

var bw = new BackgroundWorker();
bw.DoWork += Impersonated(TOKEN, (s, a) => { /* code */ });
另一种方法是继承类并重写
OnDoWork()
进行模拟,因为
BackgroundWorker
没有密封,并且它的
OnDoWork()
方法受到保护。然后,你可以做:

var bw = new ImpersonatingBackgroundWorker(...)
如上所述,将以下代码段添加到
App.config
文件就足以使
模拟跨线程边界

<configuration>
 <runtime>
   <alwaysFlowImpersonationPolicy enabled="true"/>
   <legacyImpersonationPolicy enabled="false"/>
 </runtime>
</configuration>


但是,最佳实践解决方案只在实际需要的地方使用模拟,而不是全局使用。

这是关于ASP.NET的,但原因和解决方案是相同的:这也可能有帮助:@Dennis感谢链接。第一个链接()的方法2可以完美地工作。你想把这个作为一个答案吗?嗯,答案中没有我的投资,所以,你可以自己发布答案。此外,正如它所说的,这个问题是一个广泛讨论的基础-因为这是桌面应用程序(我假设它是使用
BackgroundWorker
),这是一个大问题,为什么需要这么多地方来模拟。所以,你接受的解决方案对我来说不太好,因为在我看来,它隐藏了真正的设计问题。我完全同意“只在需要的地方模拟”,但这就是项目增长的方式。是的,好吧,你可以使用更长的模拟,但仍然可以减少重复,就像我的例子中那样。您可以做的另一件事是,注意
BackgroundWorker
不是一个密封的类,
OnDoWork()
受到保护,即继承并重写
OnDoWork()
以模拟。然后只需执行
var bw=new-impersoningbackgroundworker(…)
。但我个人更喜欢我举的例子——没有继承权。