一、核心知识点解析
1.1 分部类(Partial Class)
csharp
复制代码
public partial class MainFormT : Form
- 作用:将窗体代码分割到多个文件中(.cs 和 Designer.cs)
- 优势:分离业务逻辑与界面设计代码
- 使用场景:Windows 窗体设计器自动生成
1.2 控件事件处理模型
csharp
复制代码
// 事件订阅
this.Load += MainFormT_Load;
btnExecute.Click += btnExecute_Click;
// 事件处理方法
private void btnExecute_Click(object sender, EventArgs e)
{
// sender: 触发事件的对象(按钮)
// e: 事件参数
}
1.3 线程安全操作(跨线程访问UI)
csharp
复制代码
// 检查是否需要在UI线程执行
if (InvokeRequired)
{
Invoke(new Action(() => UpdateStatus(message, color)));
return;
}
// 或使用更简洁的写法
this.Invoke(new Action(() =>
{
// 更新UI的代码
}));
2. 数据库操作关键技术
csharp
复制代码
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, conn))
{
conn.Open();
// 执行操作
}
- SqlConnection:数据库连接对象
- SqlCommand:执行SQL命令
- using 语句:确保资源自动释放
- 参数化查询:防止SQL注入
2.2 数据绑定技术
csharp
复制代码
// DataGridView 数据绑定
dataGridViewConfigs.AutoGenerateColumns = false;
dataGridViewConfigs.DataSource = dataTable;
// 手动配置列
dataGridViewConfigs.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "colId",
HeaderText = "ID",
DataPropertyName = "ConfigId" // 绑定到DataTable的列名
});
2.3 异步编程(async/await)
csharp
复制代码
private void btnOptimize_Click(object sender, EventArgs e)
{
// UI线程更新
btnOptimize.Text = "优化中...";
btnOptimize.Enabled = false;
// 后台线程执行耗时操作
Task.Run(() =>
{
OptimizeTable();
// 完成后回到UI线程
this.Invoke(new Action(() =>
{
btnOptimize.Text = "优化表";
btnOptimize.Enabled = true;
}));
});
}
3. 配置管理
3.1 App.config 配置读取
xml
复制代码
<!-- App.config -->
<connectionStrings>
<add name="AutoCleanupDBT"
connectionString="Data Source=.;Initial Catalog=AutoCleanupDBT;Integrated Security=True" />
</connectionStrings>
csharp
复制代码
// 代码中读取
string connectionString = ConfigurationManager
.ConnectionStrings["AutoCleanupDBT"]?.ConnectionString;
3.2 数据验证
csharp
复制代码
private bool ValidateInput()
{
// 空值检查
if (string.IsNullOrWhiteSpace(txtConfigName.Text))
{
MessageBox.Show("请输入配置名称", "验证错误",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
// 范围验证
if (numMaxRows.Value <= 0)
{
MessageBox.Show("请输入大于0的行数值", "验证错误",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
return true;
}
二、常见避坑点
1. 数据库连接管理
❌ 错误做法
csharp
复制代码
// 不释放连接资源
SqlConnection conn = new SqlConnection(connString);
conn.Open();
// ... 业务逻辑
// 忘记调用 conn.Close();
✅ 正确做法
csharp
复制代码
// 使用using确保资源释放
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, conn))
{
conn.Open();
// 业务逻辑
return cmd.ExecuteNonQuery();
}
// 自动调用Dispose(),包括conn.Close()
2. 跨线程UI访问
❌ 错误做法
csharp
复制代码
Task.Run(() =>
{
// 直接访问UI控件(会抛异常)
textBox1.Text = "处理完成";
});
✅ 正确做法
csharp
复制代码
Task.Run(() =>
{
// 耗时操作...
// 回到UI线程更新
this.Invoke(new Action(() =>
{
textBox1.Text = "处理完成";
}));
});
3. 字符串拼接SQL查询(SQL注入风险)
❌ 危险做法
csharp
复制代码
string sql = $"SELECT * FROM Users WHERE Name = '{userName}'";
// 如果userName = "admin' OR '1'='1",会导致SQL注入
✅ 安全做法
csharp
复制代码
string sql = "SELECT * FROM Users WHERE Name = @UserName";
var parameters = new SqlParameter("@UserName", userName);
4. 事件处理中的内存泄漏
❌ 可能导致泄漏
csharp
复制代码
// 窗体类中
_timer.Tick += Timer_Tick;
// 窗体关闭时没有移除事件
✅ 正确管理
csharp
复制代码
private void MainFormT_FormClosing(object sender, FormClosingEventArgs e)
{
if (_timer != null)
{
_timer.Stop();
_timer.Tick -= Timer_Tick; // 移除事件订阅
_timer.Dispose();
}
}
5. DataGridView 性能优化
❌ 低性能做法
csharp
复制代码
// 逐行添加数据
foreach (var item in dataList)
{
dataGridView1.Rows.Add(item.Id, item.Name);
}
✅ 高性能做法
csharp
复制代码
// 使用数据绑定
dataGridView1.DataSource = dataList;
// 或批量添加
dataGridView1.SuspendLayout(); // 暂停布局计算
// 批量操作
dataGridView1.ResumeLayout(); // 恢复布局计算
6. 异常处理
❌ 过度捕获异常
csharp
复制代码
try
{
// 太多代码在一个try块中
var data = GetData();
ProcessData(data);
UpdateUI(data);
SaveToDatabase(data);
}
catch (Exception ex)
{
// 无法准确知道哪一步出错
MessageBox.Show("出错了");
}
✅ 精准异常处理
csharp
复制代码
try
{
var data = GetData();
}
catch (SqlException ex) // 数据库异常
{
LogDatabaseError(ex);
ShowDatabaseError();
}
catch (FileNotFoundException ex) // 文件异常
{
LogFileError(ex);
ShowFileNotFoundMessage();
}
catch (Exception ex) // 其他异常
{
LogGeneralError(ex);
ShowGeneralErrorMessage();
}
finally
{
// 清理资源
}
7. 定时器使用
❌ 线程定时器更新UI
csharp
复制代码
System.Threading.Timer timer = new System.Threading.Timer(_ =>
{
// 不能直接更新UI
label1.Text = DateTime.Now.ToString();
}, null, 0, 1000);
csharp
复制代码
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += (s, e) =>
{
// 在UI线程执行
label1.Text = DateTime.Now.ToString();
};
timer.Start();
三、最佳实践建议
1. 代码组织结构
csharp
复制代码
#region 数据库连接和状态检查
// 相关方法放在一起
#endregion
#region 事件处理方法
// 所有事件处理
#endregion
#region 核心业务方法
// 主要业务逻辑
#endregion
2. 资源管理
- 使用using语句:确保实现了IDisposable的对象被正确释放
- 及时释放大对象:特别是图片、文件流等
- 使用StringBuilder:大量字符串拼接时
3. 性能优化
csharp
复制代码
// 1. 使用批量操作
// 2. 合理使用缓存
// 3. 避免频繁的数据库查询
// 4. 使用分页加载大数据
// 5. 异步执行耗时操作
4. 可维护性
csharp
复制代码
// 1. 使用有意义的变量名和方法名
// 2. 添加注释说明复杂逻辑
// 3. 提取重复代码为方法
// 4. 使用配置文件和常量
// 5. 实现日志记录
四、学习建议
- 理解事件驱动模型:掌握WinForms的核心工作机制
- 掌握ADO.NET基础:理解连接、命令、适配器的使用
- 学习异步编程:async/await模式是现代C#的核心
- 实践异常处理:编写健壮的异常处理逻辑
- 关注性能优化:特别是大数据量时的处理
- 代码重构练习:不断优化现有代码结构