System.Timers.Timer 随着每次迭代而衰减

本文关键字:迭代 衰减 Timers Timer System | 更新日期: 2023-09-27 18:37:13

好的,所以我正在学习C#/.NET,到目前为止一直坚持使用winforms,但WPF似乎适合这个项目。

我有一个显示图像数组的 WrapPanel。有时,此数组会溢出窗口的范围。我正在尝试循环浏览"页面",直到使用计时器显示所有图像。

我将在计时器经过事件处启动我的代码示例,此时我的 WrapPanel (wrapPanel1) 已经填充并检查是否存在溢出:

public void t2_Elapsed(object source, ElapsedEventArgs e)
    {
        wrapPanel1.Dispatcher.BeginInvoke((ThreadStart)delegate 
        {
            remaining = Convert.ToInt32(imgCount) - (iteration*xDensity);
            label1.Content = iteration;
            label2.Content = remaining;
            label3.Content = imgCount;
            if (remaining <= 1)
            {
                Thickness marginTop = wrapPanel1.Margin;
                marginTop.Top = 0;
                wrapPanel1.Margin = marginTop;
                wrapPanel1.Children.Clear();
                t2.Stop();
                imgLayout();
            }
            else
            {
                Thickness marginTop = wrapPanel1.Margin;
                marginTop.Top = -((prevResY+10) * iteration);
                wrapPanel1.Margin = marginTop;
                iteration++;
            }
        });
    }

imgCount 是一个双精度值,表示 WrapPanel 中的图像总数(由于与代码中其他地方的另一个双精度值交互,因此需要为双精度值)

xDensity 是一个用户定义的 int,用于设置水平显示的图像数量。

prevResY 是每张照片的高度(所有相同的分辨率),我添加 10 以考虑填充 WrapPanel 时设置的 5px 边距。通过乘以迭代,我总是将 wrapPanel1 向上移动 1 行。

imgLayout(); 重新开始这个过程,因为每次我浏览所有页面时,我都需要检查是否有任何新图像,并将任何旧图像从末尾删除。这一切都在 imgLayout() 中处理。

更新标签只是为了在调试时可以密切关注它,它们返回的值完全符合我期望的值。

正如您可能从问题标题中收集到的那样,我的问题是,随着t2_elapsed的每次迭代,间隔似乎都会增加。如果我将间隔设置为 10ms 只是为了观察它的行为,那么延迟似乎呈指数级增长。30 秒后,延迟约为 25 秒,高于最初观察到的 0.1。RAM 使用率也在缓慢攀升,这对我来说表明,当循环重新启动时,某些资源没有被处理,不确定这是原因还是单独的问题。

希望有人能帮忙!如果我做了什么傻事,告诉我,我还在学习!

非常感谢

----更新----

好的,所以我认为这与

wrapPanel1.Children.Clear(); 

线。我删除了它,让它填满了,我没有延迟,但这显然不是最终的解决方案。无论我把那条线放在哪里,它都会重现问题。

----更新2----

好吧,我现在觉得自己很愚蠢。在启动计时器的imgLayout()方法中,我使用了:

t2.Interval = new TimeSpan(0, 0, 0, 0, 5000);
t2.Tick += new EventHandler(t2_Tick);
t2.Start();

每次循环重新启动时,我都会愚蠢地声明事件处理程序。我改为将其设置为 Window_Loaded 方法,它的工作方式与现在的预期完全一样,只是稍微整理了一下并实现了一次滚动一整页而不仅仅是一行的方法。

System.Timers.Timer 随着每次迭代而衰减

建议在处理 WPF 中的重复操作时使用 System.Windows.Threading.DispatcherTimer 。它将在差异器线程上自动执行其代码,而无需BeginInvoke