C#应用运行时每3分钟检查数据库连接,断开则终止程序
Hey there! Let's solve your problem of adding periodic database connection checks and auto-terminating the app when the connection fails. Here's a step-by-step solution tailored to your existing code:
System.Windows.Forms.Timer for Periodic Checks WinForms provides a convenient Timer component that runs on the UI thread, which is perfect for your scenario. We'll use it to trigger the connection check every 3 minutes (180,000 milliseconds).
First, let's tweak the CheckIsLocalDAOConnected method to ensure it accurately reflects the current connection state (instead of relying on a static field that might get stale):
namespace CLearning.DataAccess { public class DataAccessContext { private static bool _isSQLServiceRunning = false; // Keep your existing CheckSQLServiceStatus method unchanged public static bool CheckIsLocalDAOConnected() { try { // Test a fresh connection each time for accurate status using (var connection = new SqlConnection(GlobalConfig.ConnectionString)) { // Replace with your actual connection string access connection.Open(); return true; } } catch (Exception ex) { // Optional: Log exception details for debugging Console.WriteLine($"Connection check failed: {ex.Message}"); return false; } } } }
Note: I modified this method to create a new connection on each check. If your existing GlobalConfig.Connection.TestConnection() already reliably validates the connection, you can keep that instead of the SqlConnection code above.
Add the timer to your Form1 class to handle periodic checks and app termination:
namespace CLearning { public partial class Form1 : Form { private System.Windows.Forms.Timer _dbCheckTimer; public Form1() { InitializeComponent(); SetupDatabaseCheckTimer(); } private void SetupDatabaseCheckTimer() { _dbCheckTimer = new System.Windows.Forms.Timer(); _dbCheckTimer.Interval = 180000; // 3 minutes in milliseconds _dbCheckTimer.Tick += DbCheckTimer_Tick; _dbCheckTimer.Start(); } private void DbCheckTimer_Tick(object sender, EventArgs e) { // Stop timer during check to avoid overlapping executions _dbCheckTimer.Stop(); bool isConnected = DataAccessContext.CheckIsLocalDAOConnected(); if (!isConnected) { MessageBox.Show( "Database connection has been lost. The application will now terminate.", "Connection Lost", MessageBoxButtons.OK, MessageBoxIcon.Error); // Terminate the application gracefully Application.Exit(); // If Application.Exit() doesn't work immediately, use: // Environment.Exit(1); } // Restart timer for next check _dbCheckTimer.Start(); } protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); // Clean up timer to prevent memory leaks _dbCheckTimer?.Stop(); _dbCheckTimer?.Dispose(); } } }
Your existing Main method is solid, but we can make a small adjustment for clarity:
namespace CLearning { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Check SQL Server service status bool isServiceRunning = DataAccessContext.CheckSQLServiceStatus(); if (!isServiceRunning) { MessageBox.Show( "SQL Server service could not be started. Application will terminate.", "Service Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Initial database connection check bool isLocalDAOConnected = DataAccessContext.CheckIsLocalDAOConnected(); if (!isLocalDAOConnected) { MessageBox.Show( "Database connection is not available on the machine. The application will terminate.", "No database connection available", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Launch main form (which handles periodic checks) Application.Run(new Form1()); } } }
Key Notes:
- Adjust Interval: Change
180000to a different value if you need a check frequency other than 3 minutes. - Cleanup: Stopping and disposing the timer on form close prevents memory leaks.
- Connection Accuracy: Testing a fresh connection each time ensures we're checking the current database state, not a stale connection.
- Termination:
Application.Exit()closes all forms gracefully. UseEnvironment.Exit(1)only if you need immediate process termination.
内容的提问来源于stack exchange,提问作者user3094480

