简体   繁体   English

从子线程关闭父表单

[英]Closing parent form from child thread

I've been scratching my head on this one for a while now and despite looking for solutions, im not quite understanding the implementations (several answers on stack overflow have already been looked at) 我已经在这个问题上摸爬了一段时间了,尽管正在寻找解决方案,但我不太了解实现(已经研究了关于堆栈溢出的几个答案)

My program loads a splash page when it is opened, during which it checks for a database connection. 我的程序在打开时会加载初始页面,在此期间它会检查数据库连接。 If there is a connection, the splash page closes and the main form loads, otherwise it provides an error message then closes completely. 如果存在连接,则初始页面将关闭,并且将加载主窗体,否则它会提供错误消息,然后完全关闭。

public partial class StartupSplash : Form
{

    ThreadStart th;
    Thread thread;

    public StartupSplash()
    {
        InitializeComponent();

        th = new ThreadStart(DbAvaliable);
        thread = new Thread(th);
        thread.Start();

    }

    private void DbAvaliable()
    {

        Boolean result = false;

        using (var connectiontest = new SqlConnection("myConnString"))
            try
            {
                connectiontest.Open();
                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }

        if (result)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainWindow());

        }
        else
        {
            MessageBox.Show("Unable to establish database connection. Please check your data connection and try again.");
        }
    }
}

I understand that I can't simply call this.Close() due to cross thread issues. 我知道由于跨线程问题,我不能简单地调用this.Close() I've read something about invoking methods, but im not too clear how to achieve the result above. 我已经阅读了一些有关调用方法的内容,但我不太清楚如何获得上述结果。

Initially I tried to use form load/shown events instead of alternate threads, but the image on the forms failed to load until after the messagebox had shown the error (rather than displaying, then running the connection check) 最初,我尝试使用表单加载/显示事件而不是备用线程,但是表单上的图像无法加载,直到消息框显示错误为止(而不是先显示,然后运行连接检查)。

Could you set up an event to fire on Form2 with the results of the db check? 您是否可以使用db检查的结果来设置要在Form2上触发的事件? Subscribe to the event on Form1 and tell it to close if the conditions warrant. 在条件1上订阅事件,并告诉它关闭。

Not sure if it would work or not, but something like: 不知道它是否可以工作,但是类似:

public Form2 : Form
{
    public delegate void DbCheckHandler(object sender, DbEventArgs e);
    public event DbCheckHandler DbCheckComplete;

    //check the db
    DbCheckComplete(this, new DbEventArgs { ShouldClose = true; });

}

public Form1 : Form
{
    Form2 form2 = new Form2();
    form2.DbCheckComplete += new DbCheckHandler(CheckDbResult);
    form2.Show();

    private void CheckDbResult(object sender, DbEventArgs e)
    {
        if(e.ShouldClose)
        {
            this.Close();
        }

    }
}

With some help from previous answers posted by Hans Passant ( here and here ), My solution was as follows: Hans Passant之前此处此处 )发布的答案的帮助下,我的解决方案如下:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {   
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        new MyApp().Run(args);

    }

class MyApp : WindowsFormsApplicationBase
{
    protected override void OnCreateSplashScreen()
    {
        this.SplashScreen = new StartupSplash();
    }

    protected override void OnCreateMainForm()
    {
        Boolean result = false;
        using (var connectiontest = new SqlConnection("myConnectionString"))
            try
            {
                connectiontest.Open();
                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }
        // pause not needed while checking for db connection as that takes its own amount of time to complete.


        if (result)
        {
            System.Threading.Thread.Sleep(3000); //pause moved here to give the splash some time on screen if db connection available
            this.MainForm = new MainWindow();
        }
        else
        {
            MessageBox.Show("Unable to connect to the database");

            Environment.Exit(1); // shuts down the program if database connection not avaliable.

        }

    }


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM