我有一些我无法解决的奇怪问题...我已经使用线程创建了启动画面(Form3~SplashScreen),不知何故应用程序到达部分后
Thread.Abort的();
(实际上杀死了线程)启动屏幕停留在屏幕上,直到我在其上移动鼠标,或者在其他窗体上的某个地方点击它(例如Form1)...我变得更加困惑因为,这不是在我运行应用程序时发生在VS中。启动画面正在正常关闭...,它只发生在编译的.exe上 Program.cs的
namespace ICAMReports
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
SplashScreen.cs
namespace ICAMReports
{
public partial class SplashScreen : Form
{
public SplashScreen()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(1);
if (progressBar1.Value == 100)
{
timer1.Stop();
}
}
}
}
Form1.cs的
namespace ICAMReports
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(splashScreen));
th.Start();
Thread.Sleep(3000);
th.Abort();
}
public void splashScreen()
{
Application.Run(new SplashScreen());
}
//this where the rest of code is placed....
}
}
任何线索,为什么会发生这种情况或如何解决这个问题?
截图:
答案 0 :(得分:1)
有许多方法可以在不使用thread.Abort的情况下关闭启动画面。
这是实现你想要做的事情的一种方法。
SplashScreen.cs
namespace ICAMReports
{
public partial class SplashScreen : Form
{
ManualResetEventSlim splashDone;
public SplashScreen(ManualResetEventSlim SplashDone)
{
splashDone=SplashDone;
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(1);
if (progressBar1.Value == 100)
{
splashDone.Set();
this.Close();
} } } }
Form1.cs的
namespace ICAMReports
{
public partial class Form1 : Form
{
ManualResetEventSlim splashDone = new ManualResetEventSlim(false);
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(splashScreen));
th.Start();
splashDone.Wait();
}
public void splashScreen()
{
Application.Run(new SplashScreen(splashDone));
}
//this where the rest of code is placed....
}
}
splashDone.Wait()将完成你尝试使用Sleep()做同样的事情,但是你应该在你的启动画面中使用你的加载条告诉你何时结束线程。实际上在这种情况下,将启动屏幕放在一个单独的线程上是没有任何意义的,因为睡眠/等待会暂停主窗体加载任何内容,直到启动画面完成。假设你在Form1中有资源密集的东西,你想加载,而Splash Screen分散了用户的注意力。你会做这样的事情,而不是完全暂停Form1(因为使用一个单独的线程的全部意义是它们都同时运行。
SplashScreen.cs
namespace ICAMReports
{
public partial class SplashScreen : Form
{
Form parent;
delegate void show();
public SplashScreen(Form Parent)
{
parent=Parent;
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(1);
if (progressBar1.Value == 100)
{
parent.Invoke(new show(()=>{parent.Opacity=100;}));
this.Close();
} } } }
Form1.cs的
namespace ICAMReports
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(splashScreen));
th.Start();
this.Opacity=0;
}
public void splashScreen()
{
Application.Run(new SplashScreen(this));
}
//this where the rest of code is placed....
}
}
编辑:响应加载栏动画
根据您使用的Windows的版本和设置,加载栏将移动并显示不同。您不能使用Thread.Sleep让加载栏赶上,因为它会暂停loadingBar1动画。你需要给你的加载条约10%才能赶上(根据需要调整它)这应该可以解决你的加载条动画问题。
int i = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if(i++<100)progressBar1.Value++;
if (i == 110)
{
splashDone.Set();
this.Close();
}
}