如何避免从工作线程到 GUI 线程的主体传播
Posted
技术标签:
【中文标题】如何避免从工作线程到 GUI 线程的主体传播【英文标题】:How to avoid principal propagation from worker-thread to GUI-thread 【发布时间】:2015-07-31 20:36:39 【问题描述】:我们有一个带有工作线程的 Windows 应用程序,需要更新 GUI。我们使用 BeginInvoke 异步执行此操作。我们的问题,在下面的示例中演示,是 Principal 被传播到我们想要避免的 GUI 线程,因为在我们的实际应用程序中,我们执行的服务器请求由于错误的身份而失败。有没有办法避免这种传播?
private Thread _thread;
public Form1()
InitializeComponent();
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("MainUser"), new[] "User" );
_thread = new Thread(ThreadProc);
_thread.Start(this);
private void ThreadProc(object parameter)
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("ThreadUser"), new[] "User" );
var form = parameter as Form1;
while (true)
form.BeginInvoke(new Action(() => ShowIdentity()));
Thread.Sleep(4000);
private void ShowIdentity()
lblIdentity.Text = Thread.CurrentPrincipal.Identity.Name;
【问题讨论】:
【参考方案1】:有关在 .NET 中模拟 Windows 用户的说明,请参阅 http://blogs.msdn.com/b/shawnfa/archive/2005/03/22/400749.aspx。也就是说,如果您在客户端计算机上执行此操作,则需要在 UI 用户的帐户下访问目标帐户的密码,这可能是您不想要的。为了防止这种情况,您需要使 UI 用户可以访问服务器端服务,或者使用中间服务(例如:客户端计算机上的服务器托管或 Windows 服务)在运行时代理对服务器端服务的调用有权访问目标服务的帐户。
【讨论】:
如果我做对了,这解决了错误用户调用服务器的问题,而不是如何防止工作线程在 GUI 线程上设置主体的问题。但这仍然是一个解决方案,谢谢。【参考方案2】:所以我想您在标签上打印了名称“MainUser”?
发生的事情不是主线程的 Thread.Principal 主体正在传播到另一个线程,而是ShowIdentity
正在同一个线程(主线程)上完成!
Invoke
和 BeginInvoke
将要在创建控件的线程上完成的工作排队(或者正如 MSDN 所说的“在创建控件的底层句柄的线程上异步执行指定的委托” )。
这两种方法的区别在于Invoke
将阻塞直到工作项完成线程,而BeginInvoke
只将工作项添加到队列中并立即返回。
因此,在您的示例中,您每 4 秒从您创建的线程开始向此队列添加一个 Action
。因为 UI 线程不忙于做其他事情,它会在排队后很快处理这项工作 - 但它将在 UI 线程上运行(其关联的主体名为“MainUser”)。
这有意义吗?
【讨论】:
以上是关于如何避免从工作线程到 GUI 线程的主体传播的主要内容,如果未能解决你的问题,请参考以下文章