也许我错误地记住了Winforms的工作方式,或者我正在过度复杂化,但这是我的问题。WPF背景线程调用
我有一个WPF客户端应用程序通过WCF与服务器通话。当前用户可以“注销”WPF客户端,该客户端关闭所有打开的屏幕,仅保留导航窗格并最小化程序窗口。当用户重新最大化程序窗口时,系统会提示他们登录。简单。
但是有时候事情发生在后台线程上 - 就像客户端每5分钟尝试一次WCF调用刷新一些缓存数据一样。如果用户在5分钟计时器触发时退出,该怎么办?那么,应该提示用户重新登录...并且这当然必须在UI线程上发生。
private static ISecurityContext securityContext;
public static ISecurityContext SecurityContext
{
get
{
if (securityContext == null)
{
// Login method shows a window and prompts the user to log in
Application.Current.Dispatcher.Invoke((Action)Login);
}
return securityContext;
}
}
private static void Login()
{
if (securityContext == null) { \
/* show login window and set securityContext */
var w = new LoginWindow();
w.ShowDialog();
securityContext = w.GetSecurityContext();
}
}
到目前为止很好,对不对?但是当多个线程碰到这段代码时会发生什么?
嗯,我的第一个直觉是,因为我在Application.Current.Dispatcher中同步,我应该没问题,并且任何线程先打的负责显示登录窗体并让用户登录。 。
不是这样的......
线程1会打码,并调用ShowDialog的登录表单上
线程2也将打码,并会尽快致电登录线程1已经调用ShowDia日志,因为调用ShowDialog的畅通线程1(我相信的,因为方式的WPF消息泵作品)
...最终效果是,我有弹出用户同时多个登录表单。
我想要的是让用户重新登录到应用程序的同步方式......我在这里错过了什么?
在此先感谢。
给Paul的答案增加一点细节,我相信他说你应该锁定securityContext。这样,一旦一个线程访问并修改了securityContext(大概是登录),那么其他跟随的线程将不会弹出登录对话框,因为securityContext在访问时已经被设置。 – Dave 2010-04-27 04:06:38
好点。我应该提到我尝试过....请考虑以下事项:1.后台线程进入并调用Application Dispatcher线程,同时锁定securityContextLock对象。 2.用户单击以最大化应用程序,并且真正的UI线程进入并尝试访问securityContext ...但它被锁定....所以整个UI线程冻结...甚至认为步骤1中的人管理为了显示登录表单,UI线程被冻结,并且用户不能与登录表单交互。所以我们陷入僵局。 – Jeff 2010-04-27 04:17:57
我还应该提到忽略而不是阻塞不是一个选项,因为任何要求securityContext的线程都会立即需要它来创建WCF通道凭证。 – Jeff 2010-04-27 04:32:42