【问题标题】:Closing parent form from child thread从子线程关闭父窗体
【发布时间】:2016-07-28 17:00:23
【问题描述】:

我已经在这个问题上摸索了一段时间,尽管正在寻找解决方案,但我不太了解实现(已经查看了有关堆栈溢出的几个答案)

我的程序在打开时会加载一个启动页面,在此期间它会检查数据库连接。如果有连接,则启动页面关闭并加载主窗体,否则它会提供错误消息然后完全关闭。

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.");
        }
    }
}

我知道由于跨线程问题,我不能简单地调用this.Close()。我读过一些关于调用方法的内容,但我不太清楚如何实现上述结果。

最初我尝试使用表单加载/显示事件而不是备用线程,但在消息框显示错误(而不是显示,然后运行连接检查)之前,表单上的图像无法加载

【问题讨论】:

  • 你能不能在一个返回真或假连接的任务中做数据库,然后你就等着它关闭应用程序还是根据结果继续?
  • 它有问题,会给你带来很多痛苦。 .NET Framework 已经有 excellent support 用于启动屏幕,最好使用它。

标签: c# multithreading


【解决方案1】:

您能否设置一个事件以在 Form2 上触发数据库检查的结果?订阅 Form1 上的事件并在条件允许时告诉它关闭。

不确定它是否有效,但类似:

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();
        }

    }
}

【讨论】:

  • 不是我想要的,但还是谢谢!
【解决方案2】:

Hans Passantherehere)之前发布的答案的帮助下,我的解决方案如下:

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.

        }

    }


}

【讨论】:

    猜你喜欢
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2013-02-14
    相关资源
    最近更新 更多