跨线程访问UI异常问题?特别this.Activate()后马上抛异常

datahandler 2017-08-24 05:42:20
两个窗体,一个是主窗体MainFrm 一个是模式窗体CheckFaceFrm,
主窗体MainFrm上面点击一个按钮触发一个线程去new CheckFaceFrm(),并以模态方式弹出。
模态窗体CheckFaceFrm上面的OK按钮点击后返回DialogResult=OK给主窗体MainFrm.
然后更新主窗体MainFrm 上面的TextBox值。大意演示主要代码

var thread=new Thread(new Action(()=>{
try
{
var invoker = new MethodInvoker(new Action(() =>
{
using (var camFrm = new CheckFaceFrm())
{
var dialogResult = camFrm.ShowDialog(this);
if (dialogResult == DialogResult.OK)
{
txtResult.Text = "Invoke:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
}

}));
this.Invoke(invoker);
//this.Activate(); ------------------>如果不注释这段代码则会抛出线程间操作无效: 从不是创建控件“MainFrm”的线程访问它。
}
catch (Exception ex)
{
LogUtils.Write(ex.ToString());
}

}));

thread.Star();



this.Activate();这句代码很无奈,正常情况下弹出的ShowDialog 窗体应该是焦点窗体。但不知道为啥这个模态窗体的界面对应控件事件去调用一个合作厂家的读卡接口后。偶尔我的这个模态窗体就会被失去点击隐藏掉。甚至连主窗体也会被隐藏掉。
那这边为啥加了这句就不能再线程外访问主线程的UI了?如何改进?
...全文
292 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
楚楚3107 2017-08-25
  • 打赏
  • 举报
回复
跨线程访问要用委托来执行。你把注释的代码换成下边的试试,看看报错么 this.Invoke(new EventHandler(delegate {this.Activate();}));
  • 打赏
  • 举报
回复
实际上,所谓“读卡接口”应该经过千锤百炼反复测试,每天测试几千遍,并且并发测试。然后你调用它的代码应该经过测试(其实也不应该在 UI 线程去调用它们)。 当你的代码自身不崩溃,这时候说第三方的读卡接口有问题,就比较靠谱了。
  • 打赏
  • 举报
回复
对控件的操作,本来就应该从创建窗体的UI线程去调用。所以你的 Active 放到子线程中是不对的。 至于说第三方 UI 控件质量很差,把宿主窗体弄崩溃了,那么你应该退货。不要把自己程序弄得乱写逻辑。
xuzuning 2017-08-24
  • 打赏
  • 举报
回复
模态窗体将挂起宿主窗体,请注意他们之间的关系
上帝的亲哥哥 2017-08-24
  • 打赏
  • 举报
回复
thi.Invoke会调用UI线程,在你的子线程中调用UI线程要通过委托进行回调的。
Anonymous477 2017-08-24
  • 打赏
  • 举报
回复
通过Invoke去执行

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧