You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET7 Winform关闭时异步MySQL任务异常的解决方法

.NET7 WinForms异步查询子窗体关闭空引用问题解决

核心问题

子窗体关闭后,后台异步MySQL查询仍在运行,完成后尝试绑定已被销毁的图表控件,触发System.NullReferenceException。

正确处理方案

1. 子窗体侧管理取消令牌

在子窗体中创建CancellationTokenSource,关闭时取消令牌,终止后台任务:

public partial class ChildForm : Form
{
    private CancellationTokenSource _cts;

    public ChildForm()
    {
        InitializeComponent();
        _cts = new CancellationTokenSource();
        _ = LoadStatsAsync(_cts.Token);
    }

    private async Task LoadStatsAsync(CancellationToken token)
    {
        try
        {
            var stats = await Queries.GetStatisticsAsync(token);
            // 绑定前检查窗体未释放且任务未取消
            if (!IsDisposed && !token.IsCancellationRequested)
            {
                chart1.DataSource = stats;
                // 完成图表绑定的后续逻辑
            }
        }
        catch (OperationCanceledException)
        {
            // 任务被取消,无需处理
        }
        catch (Exception ex)
        {
            MessageBox.Show($"统计数据加载失败:{ex.Message}");
        }
    }

    protected override void OnFormClosed(FormClosedEventArgs e)
    {
        base.OnFormClosed(e);
        _cts.Cancel();
        _cts.Dispose();
    }
}

2. Queries类中集成取消令牌

将令牌传递到MySQL异步操作的每一步,确保查询能被及时终止,避免无效资源占用:

public static class Queries
{
    public static async Task<List<StatModel>> GetStatisticsAsync(CancellationToken token)
    {
        var statsList = new List<StatModel>();
        var connString = "你的MySQL连接字符串";
        
        using var conn = new MySqlConnection(connString);
        await conn.OpenAsync(token);
        
        var query = "SELECT record_date, stat_value FROM statistics_table";
        using var cmd = new MySqlCommand(query, conn);
        using var reader = await cmd.ExecuteReaderAsync(token);
        
        while (await reader.ReadAsync(token))
        {
            statsList.Add(new StatModel
            {
                RecordDate = reader.GetDateTime(0),
                StatValue = reader.GetInt32(1)
            });
        }
        
        return statsList;
    }
}

3. 绑定前的双重防护

即使任务没被取消,也可能存在窗体已释放的情况,必须在绑定图表前做检查,避免空引用:

if (!this.IsDisposed && !token.IsCancellationRequested)
{
    // 执行图表绑定操作
}

关键注意点

  • 窗体关闭时必须调用_cts.Cancel()和_cts.Dispose(),防止资源泄漏。
  • 所有MySQL异步方法都要传入取消令牌,才能真正终止正在执行的查询,而不是只在代码层面判断。
  • OperationCanceledException是任务被取消的正常结果,不需要弹出错误提示。

内容的提问来源于stack exchange,提问作者Ivaylo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:30:09