Catch problems, protect your app, and guide the user
In desktop apps, things can go wrong: the user enters invalid data, a file canβt be found, or a device is disconnected. Without proper error handling, your app can crash or behave unpredictably.
In C#, we use try, catch, and finally blocks to detect, handle, and clean up errors β making your WinForms apps safe and user-friendly.
π§± Basic Structure
try
{
// Code that might cause an error
}
catch (Exception ex)
{
// What to do if an error occurs
}
finally
{
// Code that always runs (optional)
}
β Example: Safe File Reading
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
string content = File.ReadAllText("mydata.txt");
txtOutput.Text = content;
}
catch (FileNotFoundException)
{
MessageBox.Show("The file was not found.");
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("You donβt have permission to open this file.");
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong: " + ex.Message);
}
finally
{
// Optional: cleanup or logging
Console.WriteLine("Load attempt finished.");
}
}
β
Multiple catch blocks = more specific handling
β
finally runs even if an error or success happens
π§ Why Use try/catch?
| Benefit | Description |
|---|---|
| Prevent app crashes | Catch and respond to unexpected problems |
| Guide the user | Show helpful error messages (not raw exceptions) |
| Clean up resources | Close files or connections in finally |
| Improve maintainability | Easier to debug when something fails |
π― Example: Input Validation
private void btnDivide_Click(object sender, EventArgs e)
{
try
{
int a = int.Parse(txtA.Text);
int b = int.Parse(txtB.Text);
int result = a / b;
lblResult.Text = $"Result: {result}";
}
catch (DivideByZeroException)
{
MessageBox.Show("You can't divide by zero!");
}
catch (FormatException)
{
MessageBox.Show("Please enter valid numbers.");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
π Using finally
The finally block runs no matter what, making it ideal for cleanup:
FileStream stream = null;
try
{
stream = File.Open("example.txt", FileMode.Open);
// Do something with the stream
}
catch (Exception ex)
{
MessageBox.Show("Problem opening file: " + ex.Message);
}
finally
{
if (stream != null)
stream.Close(); // Always close the file
}
β Even if an error happens, the file still gets closed
π§ͺ Quick Challenge
π§© Create a form that:
- Accepts two numbers and divides them
- Catches divide-by-zero and format errors
- Shows the result in a label
- Logs each attempt to a file in a
finallyblock
π Summary
| Block | Purpose |
|---|---|
try | Run risky code |
catch | Handle specific or general exceptions |
finally | Always runs β perfect for cleanup |
ex.Message | Detailed message from the caught exception |
β Best Practices
- β
Catch specific exceptions first (
FileNotFoundException, etc.) - β
Avoid empty
catchblocks β always handle or log the error - β
Use
finallyto clean up open files, DB connections, etc. - β Show friendly messages to users (not raw errors)
- β Log exceptions to a file or diagnostic tool for dev review
π Want to Go Further?
- Log errors to a file using
StreamWriter - Display exception details in a custom error dialog
- Use
Application.ThreadExceptionto catch global UI errors - Create a reusable error handler method or class
π¬ Want help setting up safe error handling in your form or logging failures for debugging?
Send your current code β Weβll help you wrap it in robust try/catch logic in our WinForms C# Training Course.