在Close窗体之前,怎么判断ClosingWhileCreatingHandle?

泡泡龙 2014-07-01 12:04:00
我用线程创建了一个窗体,然后在主线程里面关闭它。

某些特殊情况想,关闭的太快了,就会出现ClosingWhileCreatingHandle错误。

怎么在Close之前,判断一下呢?如果窗体没创建完毕,就等一会。判断visible行不行?


或者谁有什么简单办法,能够在 thread.start() 之后,得知线程已经把窗体打开了,窗体可以等着被关闭了?

...全文
175 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
落叶1210 2014-07-01
  • 打赏
  • 举报
回复
干脆把为什么这么做的原因写出来,别人好帮你分析。
落叶1210 2014-07-01
  • 打赏
  • 举报
回复
代码没看,但看你的思路是有问题的,为什么不在同一个线程里关闭窗体?
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
ts = new Thread(new ThreadStart(ShowProgressForm)); ts.IsBackground = true; ts.SetApartmentState(ApartmentState.STA); ts.Start(); this.LoadPeriods(this, new EventArgs()); //因为线程启动进度条窗体是需要时间的,所以下面的代码等待进度条窗体启动。 while (fpb == null && fpb.Visible!=true) { Thread.Sleep(10); } Thread.Sleep(40); //因为是.ShowDialog()启动,所以需要人工Dispose窗体 if (fpb != null) { fpb.SafeBeginInvoke(d => d.Close()); fpb.SafeBeginInvoke(d => d.Dispose()); } fpb是类里面的私有变量,是ts里面启动的进度条窗体 private void ShowProgressForm() { if (fpb != null) { fpb.SafeBeginInvoke(d => d.Close()); fpb.SafeBeginInvoke(d => d.Dispose()); } //Application.EnableVisualStyles(); fpb = new FormProgressBar("提示..."); fpb.ProgressStyle = ProgressBarStyle.Marquee; fpb.DisplayPercent = false; fpb.ShowDialog(); }
tinydyw 2014-07-01
  • 打赏
  • 举报
回复
看你子窗体是做什么的...交给子窗体做的事一般都是异步委托处理的吧..把关闭代码写到异步委托的回调函数里...如果是同步...那你等到固定时间(这个时间大于创建窗体的时间)检测子窗体要处理的事情是否完成..完成就关闭就好了呗
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用 16 楼 Z65443344 的回复:
比如在主线程中设置个public bool IsShowing变量 线程先判断主窗体是否要打开子窗体,如果线程启动后,主窗体逻辑已经执行完毕,不需要开窗体了,就直接退出. 如果线程启动后,依然要求打开子窗体,那么打开子窗体,同时加个变量标识子窗体已经打开过,不要再打开了 如果主窗体通知关闭,那么退出循环,关闭窗体.
这个主意也不错,不过那个子线程的进度条窗体因为要采用滚动效果,貌似不能用show,只能用showdialog 所以,没法在线程里面使用while循环 大概还得用委托或者事件吧,还有什么好主意吗? 谢谢
於黾 2014-07-01
  • 打赏
  • 举报
回复
比如在主线程中设置个public bool IsShowing变量 线程中
bool IsShown=false;
while(IsShowing)
{
if(! IsShown)
{
form2.show();
}
thread.sleep(100);
}
if(IsShown)
{
form2.close();
}
线程先判断主窗体是否要打开子窗体,如果线程启动后,主窗体逻辑已经执行完毕,不需要开窗体了,就直接退出. 如果线程启动后,依然要求打开子窗体,那么打开子窗体,同时加个变量标识子窗体已经打开过,不要再打开了 如果主窗体通知关闭,那么退出循环,关闭窗体.
於黾 2014-07-01
  • 打赏
  • 举报
回复
引用 14 楼 liucqa 的回复:
顺便问问诸位,即使是主线程通知子线程关闭窗体,就一定能确保close在窗体完成CreatHandle之后才执行吗?如果通知早了,会不会也发生一楼的情况?
可以在子窗体中用timer来判断,不用while(true) 或者,你子窗体本来就是在线程中开启的,线程开启了子窗体后不要不管了,让它while(true)等待主窗体指令 如果主窗体给的太早,线程就可以直接退出了,而不用先开窗体再关窗体.
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
顺便问问诸位,即使是主线程通知子线程关闭窗体,就一定能确保close在窗体完成CreatHandle之后才执行吗?如果通知早了,会不会也发生一楼的情况?
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用
主窗体应该只负责通知,然后弹出窗体自己的逻辑执行完了自己关闭,而不是主窗体直接去操作 否则就变成主窗体依赖子窗体的当前状态,你要传的参数多了去了
嗯,有道理,怎么通知线程里面的窗体改关闭呀?我看好多例子用的是while(true) 有没有别的方法?或者委托?主线程里面定义一个事件,让子线程订阅? 有没有简洁代码能参考的,太复杂的话,还不如访问子窗体的属性来的省事
於黾 2014-07-01
  • 打赏
  • 举报
回复
引用 11 楼 liucqa 的回复:
[quote=引用 4 楼 Z65443344 的回复:] 各种奇葩需求. 哪里打开的就在哪里关闭,否则就算你现在弄好了,以后也会相当混乱. 各种线程都想要去操作窗体,然后另外的各种线程都想要关闭窗体,你不头大么... 什么叫低耦合,高复用? 按你现在的逻辑,这个线程代码如果要改,跟它交互的其他线程代码全部都要改.
是否奇葩不好说,进度条窗体本来就是应该由主窗体通知关闭的。现在的问题是,主窗体通知线程里面的窗体Close的时候,窗体还没有CreatHandle完毕,导致报错,你明白我的意思了吧 [/quote] 主窗体应该只负责通知,然后弹出窗体自己的逻辑执行完了自己关闭,而不是主窗体直接去操作 否则就变成主窗体依赖子窗体的当前状态,你要传的参数多了去了
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
各种奇葩需求. 哪里打开的就在哪里关闭,否则就算你现在弄好了,以后也会相当混乱. 各种线程都想要去操作窗体,然后另外的各种线程都想要关闭窗体,你不头大么... 什么叫低耦合,高复用? 按你现在的逻辑,这个线程代码如果要改,跟它交互的其他线程代码全部都要改.
是否奇葩不好说,进度条窗体本来就是应该由主窗体通知关闭的。现在的问题是,主窗体通知线程里面的窗体Close的时候,窗体还没有CreatHandle完毕,导致报错,你明白我的意思了吧
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
谁还有好主意?
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用 9 楼 Z65443344 的回复:
[quote=引用 8 楼 liucqa 的回复:] [quote=引用 3 楼 luoye4321 的回复:] 干脆把为什么这么做的原因写出来,别人好帮你分析。
莫非我得在窗体里面写个事件,然后主线程触发这个事件来关闭窗体? 但是貌似也没解决线程还没启动完成,主线程就要求关闭窗体的问题呀! [/quote] 哪个线程启动的窗体,你让它自己去关闭 加个全局变量,主线程修改这个变量,通知线程要关闭窗体了 线程检测到这个变量,再去看看窗体是否已经打开了,打开了就关闭,没打开就不用关闭了 涉及到UI的问题,能不跨线程操作最好不要,否则又要加委托,怪麻烦的.[/quote] 现在的问题就是我没法知道窗体是不是完整打开了,当fpb!=null的时候,执行Close依然可能报错。 你有什么办法解决这个问题?
於黾 2014-07-01
  • 打赏
  • 举报
回复
引用 8 楼 liucqa 的回复:
[quote=引用 3 楼 luoye4321 的回复:] 干脆把为什么这么做的原因写出来,别人好帮你分析。
莫非我得在窗体里面写个事件,然后主线程触发这个事件来关闭窗体? 但是貌似也没解决线程还没启动完成,主线程就要求关闭窗体的问题呀! [/quote] 哪个线程启动的窗体,你让它自己去关闭 加个全局变量,主线程修改这个变量,通知线程要关闭窗体了 线程检测到这个变量,再去看看窗体是否已经打开了,打开了就关闭,没打开就不用关闭了 涉及到UI的问题,能不跨线程操作最好不要,否则又要加委托,怪麻烦的.
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用 3 楼 luoye4321 的回复:
干脆把为什么这么做的原因写出来,别人好帮你分析。
莫非我得在窗体里面写个事件,然后主线程触发这个事件来关闭窗体? 但是貌似也没解决线程还没启动完成,主线程就要求关闭窗体的问题呀!
  • 打赏
  • 举报
回复
主要是现在程序员的老师真的不思进取了
泡泡龙 2014-07-01
  • 打赏
  • 举报
回复
引用 5 楼 dogfish 的回复:
创建完成后,在窗体的tag放个值。检测那个值。
好主意
Dogfish 2014-07-01
  • 打赏
  • 举报
回复
创建完成后,在窗体的tag放个值。检测那个值。
於黾 2014-07-01
  • 打赏
  • 举报
回复
各种奇葩需求. 哪里打开的就在哪里关闭,否则就算你现在弄好了,以后也会相当混乱. 各种线程都想要去操作窗体,然后另外的各种线程都想要关闭窗体,你不头大么... 什么叫低耦合,高复用? 按你现在的逻辑,这个线程代码如果要改,跟它交互的其他线程代码全部都要改.
tinydyw 2014-07-01
  • 打赏
  • 举报
回复
引用 19 楼 liucqa 的回复:
[quote=引用 18 楼 tinydyw 的回复:] 看你子窗体是做什么的...交给子窗体做的事一般都是异步委托处理的吧..把关闭代码写到异步委托的回调函数里...如果是同步...那你等到固定时间(这个时间大于创建窗体的时间)检测子窗体要处理的事情是否完成..完成就关闭就好了呗
子窗体是个进度条显示,现在的问题是主线程在子线程的窗体还没有创建完毕的时候,就去操作close,导致报错。 我尝试用visible=true属性,或者自己搞个属性,应该都可以判断窗体是否创建完毕。也能解决这个问题,但是感觉不太好。 我觉得这个问题虽然概率很低,但是如果做一个严谨的进度条窗体的话,应该有什么专业一点的办法来防止过早通知子窗体执行close吧[/quote] 严谨的进度条窗体应该是由子线程去执行操作的...(比如复制)..然后进度条实时更新..这样就一定会有一个变量去保存进度条的进行状况..你可以拿那个变量来判断...不过现在我也不清楚你的进度条是怎么写的...
加载更多回复(2)

110,533

社区成员

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

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

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