winforms 如何在c#中加快foreach循环?

rkttyhzu  于 2023-01-09  发布在  C#
关注(0)|答案(1)|浏览(283)

我的timer_tick方法中有这段代码,每10毫秒调用一次,除非我在列表中添加更多控件,否则它运行正常。
我试着在while()循环中用Thread. sleep在线程中运行它,但它似乎冻结了我的整个窗体。
我怎样才能使这段代码运行得更快并改变控件的位置?控件的类型有区别吗?我应该使用面板而不是图片框吗?
下面是我的代码:

private void notepreview_Tick(object sender, EventArgs e)
{
    
    Invoke(new Action(() =>
    {
        foreach (PictureBox picbox in activeNotes)
        {
            picbox.Location = new Point(picbox.Location.X, picbox.Location.Y + 1);
            //Console.WriteLine("x: " + picbox.Location.X);
            //Console.WriteLine("y: " + picbox.Location.Y);

            if (picbox.Location.Y > this.Height + 5)
            {
                picbox.Dispose();
                tabPage16.Controls.Remove(picbox);
            }
        }
    }));

}

这是它在我的表单中的样子(每个音符都是单独产生的,因此延迟会缓慢上升,导致与音频和钢琴不同步)
imgur form lag showcase
也许我应该用gdi+来代替?它会提高性能吗?
我试着在这个问题之外的单独线程中运行代码:Accessing a form's control from a separate thread
(听说使用FOR循环而不是foreach更快,但在这种情况下并没有真正的区别)

iszxjhcz

iszxjhcz1#

您可以尝试在窗体上围绕循环调用SuspendLayoutResumeLayout,这样它就不会为每个控件更新自身......但除此之外,如果它没有帮助,可能没有好的方法可以使它更快。
与其在窗体上使用多个PictureBox来为每个音符设置动画,不如考虑将移动音符矩形的整个场景绘制到一个Graphics上,然后再渲染到一个PictureBox上。这也有一个方便的特性,即能够完全确定地渲染,因此您可以精确地为音频计时。

相关问题