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();
}
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();
}
但是貌似也没解决线程还没启动完成,主线程就要求关闭窗体的问题呀!
哪个线程启动的窗体,你让它自己去关闭
加个全局变量,主线程修改这个变量,通知线程要关闭窗体了
线程检测到这个变量,再去看看窗体是否已经打开了,打开了就关闭,没打开就不用关闭了
涉及到UI的问题,能不跨线程操作最好不要,否则又要加委托,怪麻烦的.现在的问题就是我没法知道窗体是不是完整打开了,当fpb!=null的时候,执行Close依然可能报错。你有什么办法解决这个问题?
是否奇葩不好说,进度条窗体本来就是应该由主窗体通知关闭的。现在的问题是,主窗体通知线程里面的窗体Close的时候,窗体还没有CreatHandle完毕,导致报错,你明白我的意思了吧
是否奇葩不好说,进度条窗体本来就是应该由主窗体通知关闭的。现在的问题是,主窗体通知线程里面的窗体Close的时候,窗体还没有CreatHandle完毕,导致报错,你明白我的意思了吧
主窗体应该只负责通知,然后弹出窗体自己的逻辑执行完了自己关闭,而不是主窗体直接去操作
否则就变成主窗体依赖子窗体的当前状态,你要传的参数多了去了
或者,你子窗体本来就是在线程中开启的,线程开启了子窗体后不要不管了,让它while(true)等待主窗体指令
如果主窗体给的太早,线程就可以直接退出了,而不用先开窗体再关窗体.
线程中
bool IsShown=false;
while(IsShowing)
{
if(! IsShown)
{
form2.show();
}
thread.sleep(100);
}
if(IsShown)
{
form2.close();
}
线程先判断主窗体是否要打开子窗体,如果线程启动后,主窗体逻辑已经执行完毕,不需要开窗体了,就直接退出.
如果线程启动后,依然要求打开子窗体,那么打开子窗体,同时加个变量标识子窗体已经打开过,不要再打开了
如果主窗体通知关闭,那么退出循环,关闭窗体.
这个主意也不错,不过那个子线程的进度条窗体因为要采用滚动效果,貌似不能用show,只能用showdialog所以,没法在线程里面使用while循环大概还得用委托或者事件吧,还有什么好主意吗?谢谢
子窗体是个进度条显示,现在的问题是主线程在子线程的窗体还没有创建完毕的时候,就去操作close,导致报错。我尝试用visible=true属性,或者自己搞个属性,应该都可以判断窗体是否创建完毕。也能解决这个问题,但是感觉不太好。我觉得这个问题虽然概率很低,但是如果做一个严谨的进度条窗体的话,应该有什么专业一点的办法来防止过早通知子窗体执行close吧
public void Close()
{
if (base.GetState(0x40000))
{
throw new InvalidOperationException(SR.GetString("ClosingWhileCreatingHandle", new object[] { "Close" }));
}
if (base.IsHandleCreated)
{
this.closeReason = CloseReason.UserClosing;
base.SendMessage(0x10, 0, 0);
}
else
{
base.Dispose();
}
}
子窗体是个进度条显示,现在的问题是主线程在子线程的窗体还没有创建完毕的时候,就去操作close,导致报错。我尝试用visible=true属性,或者自己搞个属性,应该都可以判断窗体是否创建完毕。也能解决这个问题,但是感觉不太好。我觉得这个问题虽然概率很低,但是如果做一个严谨的进度条窗体的话,应该有什么专业一点的办法来防止过早通知子窗体执行close吧
严谨的进度条窗体应该是由子线程去执行操作的...(比如复制)..然后进度条实时更新..这样就一定会有一个变量去保存进度条的进行状况..你可以拿那个变量来判断...不过现在我也不清楚你的进度条是怎么写的...