正在从子线程关闭父窗体
本文关键字:窗体 线程 | 更新日期: 2023-09-27 17:58:48
我对这个问题已经有一段时间了,尽管我在寻找解决方案,但我并不完全理解实现(已经研究了关于堆栈溢出的几个答案)
我的程序在打开时加载一个启动页,在此期间检查数据库连接。如果存在连接,启动页将关闭,主窗体将加载,否则它将提供一条错误消息,然后完全关闭。
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()
。我读过一些关于调用方法的文章,但我不太清楚如何实现上面的结果。
最初,我尝试使用表单加载/显示事件而不是备用线程,但表单上的图像未能加载,直到消息框显示错误(而不是显示,然后运行连接检查)
您能设置一个事件,用数据库检查的结果在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();
}
}
}
在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.
}
}
}