2

我们有一个带有需要更新 GUI 的工作线程的 Windows 应用程序。我们使用 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;
  }
4

2 回答 2

0

有关在 .NET 中模拟 Windows 用户的说明,请参阅http://blogs.msdn.com/b/shawnfa/archive/2005/03/22/400749.aspx。也就是说,如果您在客户端计算机上执行此操作,则需要在 UI 用户的帐户下访问目标帐户的密码,这可能是您不想要的。为了防止这种情况,您需要使 UI 用户可以访问服务器端服务,或者使用中间服务(例如:客户端计算机上的服务器托管或 Windows 服务)在运行时代理对服务器端服务的调用有权访问目标服务的帐户。

于 2015-05-20T14:08:35.143 回答
0

所以我想你在标签上打印了名字“MainUser”?

发生的事情不是主线程的 Thread.Principal 主体正在传播到另一个线程,而是ShowIdentity在同一个线程(主线程)上完成!

InvokeBeginInvoke排队要在创建控件的线程上完成的工作(或者正如MSDN所说的“在创建控件的底层句柄的线程上异步执行指定的委托”)。

这两种方法之间的区别在于,Invoke将阻塞直到工作项完成线程,而BeginInvoke仅将工作项添加到队列中并立即返回。

因此,在您的示例中,您Action每 4 秒从您创建的线程添加一个到此队列。因为 UI 线程不忙于做其他事情,它会在排队后很快处理这项工作 - 但它将在 UI 线程上运行(其关联的主体名为“MainUser”)。

那有意义吗?

于 2016-11-22T12:49:27.033 回答