我们有一个带有工作线程的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;
}
答案 0 :(得分:0)
有关在.NET中模拟Windows用户的说明,请参阅http://blogs.msdn.com/b/shawnfa/archive/2005/03/22/400749.aspx。也就是说,如果您在客户端计算机上执行此操作,则需要在UI用户的帐户下访问目标帐户的密码,这可能是您不想要的。为了防止这种情况,您需要使UI用户可以访问服务器端服务,或者使用中间服务(例如:客户端计算机上的服务器托管或Windows服务)来代理服务器端服务的调用。可以访问目标服务的帐户。
答案 1 :(得分:0)
所以我想你在标签上印有“MainUser”这个名字?
正在发生的事情是不主线程的Thread.Principal主体正在传播到另一个线程,而是ShowIdentity
正在同一个线程上完成(主线程) )!
Invoke
和BeginInvoke
排队工作要在创建控件的线程上完成(或者MSDN将其置于“在控件的线程上异步执行指定的委托”底层句柄是在“)上创建的。
两种方法之间的区别在于Invoke
将阻塞直到工作项完成线程,而BeginInvoke
仅将工作项添加到队列并立即返回。
因此,在您的示例中,您每隔4秒从您创建的线程向此队列添加一个Action
。因为UI线程并不忙于执行其他操作,所以它将在排队后很快处理这项工作 - 但它将在UI线程上运行(其关联的主体名为“MainUser”)。
这有意义吗?