先说下背景,程序启动时,用一个线程跑登录窗口页面,主线程继续运行,当登录窗结束时执行Application.Current.MainWindow.Show();显示主页面。此时不报错!
报错的场景:当密码过期时,再子线程内弹出一个修改密码页面,修改完成后登录窗结束继续执行Application.Current.MainWindow.Show();时就报错了,报错内容:调用线程无法访问此对象,因为另一个线程拥有该对象,但是明明这句话是在主线程的程序里写的,不知道怎么就被占用了,尝试了:
Application.Current.MainWindow.Dispatcher.Invoke(new Action(() =>
{
Application.Current.MainWindow.Show();
}));
还是同一个错误;
又尝试 去掉子线程弹出修改密码页面发现不报错,原因就是出在子线程又弹出页面了么?求大神解惑,五十豆不成敬意
主程序的代码,子线程登录界面
// 使用登陆线程显示登陆窗口
var loginThread = new System.Threading.Thread(() => {
var login = App.LoginView = new LoginView(); login.Show();
// 允许主线程继续执行
Mre.Set();
login.Closed += (s, arg) => login.Dispatcher.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Background); System.Windows.Threading.Dispatcher.Run();
Mre.Set();
// 当以非正常方式(如Alt+F4)关闭登陆窗口时,Result属性还没有进行设置,此时将设置为false等同于点击退出按钮关闭
if (login.Result == null)
{ login.Result = false; }
});
loginThread.SetApartmentState(System.Threading.ApartmentState.STA); loginThread.Start();
// 等待登陆线程完成实例创建的操作
Mre.WaitOne();
Mre.Reset();
new Bootstrapper().Run();
登录界面 登录成功之后 就是这个判断里面 如果 不ShowDialog这个页面 就不会报错,show了之后 就是标题那种错误
//判断用户密码是否过期
if(密码过期)
{
ChangePW cp = new ChangePW(pwdPassword.Password);
cp.Owner = this;
cp.ShowDialog();
}
最后WPF客户端宿主启动程序,Bootstrapper类 等待登录结束之后 show主页面 具体错的位置是标红的
protected override void InitializeModules()
{ base.InitializeModules();
App.Mre.WaitOne();
if (App.LoginView.Result == true)
{
Application.Current.MainWindow.Show();
}
else { App.Current.Shutdown(); }
多线程之间,主线程的控制等等是被保护的
在新建的子线程中
this.Invoke(new Action(() =>
{
Application.Current.MainWindow.Show();
}));
用this即可
主要是我这句Application.Current.MainWindow.Show(); 是在主线程的代码里写的, 子线程执行的时候,不知道为什么弹出一个window之后就让这个子线程占用了Application.Current.MainWindow这个资源,如果子线程不弹出那个window是不报错的,我试试新建一个子线程
@狂狗A地板: 我当时用winform的时候,this.Invoke可以在多线程上面随意操作主线程新建的对象。wpf就不清楚了,this.Invoke没办法解决吗?
wpf是.Dispatcher.Invoke 按说是可以解决的,但是这个太操蛋了,对这个错误就是解决不了
@狂狗A地板: WPF是 this.Dispatcher.Invoke
用BeginInvoke
this.Dispatcher.BeginInvoke(new UpdateForm_dl(UpdateForm), new object[] { "我是文本框", "haha" });
你把你代码贴出来吧。你这一点点的挤谁知道什么情况。
代码太多,主要的贴出来了有点乱,麻烦大哥瞄一眼
再原有主程序页面实现这个功能 不放在子线程执行了