防溅板没有正常关闭

时间:2013-06-03 10:58:36

标签: c# multithreading screen splash

我有一些我无法解决的奇怪问题...我已经使用线程创建了启动画面(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....
    }
}

任何线索,为什么会发生这种情况或如何解决这个问题?

截图:Splashscreen not closing after Form1 is loaded...

1 个答案:

答案 0 :(得分:1)

MSDN说关于thread.Abort,“调用此方法通常会终止线程。”

有许多方法可以在不使用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();
        }
    }