C# 奇怪的行为

C# 奇怪的行为,c#,timer,C#,Timer,我在窗体中使用了一个Windows.Forms.Timer,如果我在属性窗口中将其Enabled属性设置为true,该计时器就会工作,而这是它唯一工作的时间。如果我让它处于禁用状态,那么只在需要时启用它,它不会滴答作响 private void btnRename_Click(object sender, EventArgs e) { timerUpdateProgress.Enabled = true; timer

我在窗体中使用了一个Windows.Forms.Timer,如果我在属性窗口中将其
Enabled
属性设置为true,该计时器就会工作,而这是它唯一工作的时间。如果我让它处于禁用状态,那么只在需要时启用它,它不会滴答作响

        private void btnRename_Click(object sender, EventArgs e)
        {
            timerUpdateProgress.Enabled = true;
            timerUpdateProgress.Start();
            pbProgress.Maximum = clbFiles.CheckedItems.Count;
            var renameTask = Task.Factory.StartNew(() => doRename(true, tbCurrentDirectory.Text, clbFiles.CheckedItems, rules));
            if(renameTask.Result.Count > 0)
            {
                timerUpdateProgress.Enabled = false;
                new ExceptionsWindow(renameTask.Result).ShowDialog();
            }
            timerUpdateProgress.Enabled = false;
            loadFiles(tbCurrentDirectory.Text);
        }

        private void timerUpdateProgress_Tick(object sender, EventArgs e)
        {
            pbProgress.Value = progress; //I have a breakpoint on this line
        }
我所要做的就是用进度条显示操作的进度。启用和启动计时器不起任何作用,滴答声永远不会发生。为什么会这样

更新:在启用和启动计时器后添加2000ms睡眠后,单步执行代码显示它仍然没有滴答声(滴答声处理程序中有一个断点)

更多说明:在属性窗口中启用计时器时,始终会调用tick处理程序,而不调用
Start()
。只要启用计时器,我的断点就会一直被触发。我还应该注意,我使用的是.NET4。

Task.Factory.StartNew花了多长时间?(如果这是同步的)

如果上面的lambda表达式是异步的,我将查看renameTask.Result.Count是否大于0,进度条=false…

编辑: 从评论中获得想法后-您似乎根本不需要计时器

progress
的值更新时,您可以更新进度条

这样,从0%到100%的过渡可能也会更平滑


据我说,你需要禁用定时器

只用

timer.Stop();
然后在需要时再次启动计时器

此外,如果已禁用计时器进度,则还必须执行

timerUpdateProgress.Enabled = true

禁用/启用的原因是什么。为什么不在需要时停止/启动?进度中的值是多少??这是在更新吗?看来你没有给你的计时器太多的时间来计时。您使用的间隔时间是多少?在上面的代码中,计时器运行的唯一时间是大约4-5行代码,可能需要几毫秒。@Davidlydbrookes他们做了同样的事情:@RobinMaben是的,它正在更新@onemancat的
doRename
方法是一个循环,因此它应该有一些时间来完成,特别是因为它涉及IO。即使在那时,我也尝试在那里添加一个
线程.Sleep()
,以便在启用和启动它之后给它时间,但它仍然不起作用。我不知道我是否诚实。我不太理解C#线程,这是SO向我推荐的,它很有效,所以我一直坚持使用它。我来自Java,在Java中创建线程就像实现接口一样简单。最后,取得了一些进展!(请原谅这个双关语)我在属性中启用了计时器,然后在
初始化组件()
之后在我的表单构造函数中使用了
timerupdateproges.Stop()
。然后,当我单击启动操作的按钮时,我使用
timerUpdateProgress.Start()
,然后当操作完成时,我再次停止它。这取得了一些成功,但看起来操作仍在计时器滴答声之前完成。如果操作(有时)在计时器滴答声之前完成,则您还需要更新进度条,而不仅仅是在计时器滴答声事件上。我根本不会使用计时器:相反,只要代码更新
progress
(看起来像一个类字段),就更新条。当然你不能更新非UI线程上的进度条,我收集的是由
Task.Factory.StartNew
创建的。如果工作线程控制进度更新,则需要同步到UI线程(为此使用
control.Invoke
control.BeginInvoke
)。当我们进行线程同步时,您的代码是否同步读取/写入共享变量
progress
?如果没有,则存在竞态条件。这是我最初遇到的情况,但我遇到了从非UI线程访问UI的问题,这就是为什么我使用计时器试图回避这个问题。BackgroundWorker正是为这种情况而设计的。如果您不介意将逻辑绑定到System.Windows.Forms命名空间,那么它是最简单的选项-