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

使用Controls.Add结合async函数无法绘制下落音符的问题排查

问题分析与解决方案

你的问题核心是跨线程操作WinForms控件:你通过Task.Run(() => CreateAndDropNotes())把音符生成和下落逻辑放到了后台线程,但WinForms控件只能由创建它们的UI线程操作,后台线程直接执行Controls.Add(notebox)、修改notebox.Location这类操作时,控件无法正确渲染——这就是音符不显示的原因,而MessageBox可以在非UI线程弹出,所以你能看到弹窗但看不到音符。

修复步骤

  1. 去掉后台线程调用:不要用Task.Run启动CreateAndDropNotes,直接在UI线程调用该异步方法(Form构造函数中可以用弃元运算符_ = CreateAndDropNotes();,或者移到Form1_Load中await执行)。
  2. 利用异步方法的线程上下文:异步方法在UI线程启动时,await后会自动回到UI线程,后续的控件添加、位置修改操作就能正常生效。

修改后的关键代码

构造函数修改

public Form1()
{
    InitializeComponent();
    InitializeTouchAreas();
    InitializeSongPattern();

    string backgroundPath = "D:\\VS Projects\\osu_2\\Resources\\background.png";
    Bitmap background = new Bitmap(backgroundPath);
    BackgroundImage = background;

    SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
    UpdateStyles();

    // 直接在UI线程启动异步方法,无需Task.Run
    _ = CreateAndDropNotes();
}

CreateAndDropNotes方法优化(简化查找逻辑+资源释放)

private async Task CreateAndDropNotes()
{
    foreach (var note in songNotes)
    {
        await Task.Delay(note.Time);

        // 用FirstOrDefault简化TouchArea查找
        TouchArea targetArea = touchAreas.FirstOrDefault(area => (Keys)area.Tag == note.Key);

        if (targetArea != null)
        {   
            PictureBox notebox = DrawNotes(targetArea, note);

            while (notebox.Location.Y < targetArea.Location.Y)
            {
                await Task.Delay(20);
                // 现在在UI线程,直接修改位置即可
                notebox.Location = new Point(notebox.Location.X, notebox.Location.Y + 5);
            }

            Controls.Remove(notebox);
            notebox.Dispose(); // 释放图片资源,避免内存泄漏
        }
    }
}

额外优化建议

  • 图片路径不要写死绝对路径,改用项目资源文件或相对路径,提升代码可移植性。
  • 可以给音符添加Tag标记对应按键,后续处理按键判定时更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:53:16