我在C#中有一个1秒的计时器,其中有一个while序列。我的问题是,如果while序列在1秒之前没有完成,计时器是否会打勾,并从头开始重新启动?
代码的一部分在下面,它的作用是循环选定的对象并改变一些东西。因此,如果选择了很多对象并且我需要超过1秒来更改它们,它们都会被更改吗?
P.S。我实际上希望循环被打破;只会错误地选择大量的物体,但我只是想确保我避免这种可能性。 :)
private void timer1_Tick(object sender, EventArgs e)
{
TSM.ModelObjectEnumerator myEnum = null;
myEnum = new TSM.UI.ModelObjectSelector().GetSelectedObjects();
while (myEnum.MoveNext())
{
if (myEnum.Current != null)
{....}
}
}
答案 0 :(得分:5)
是的,计时器滴答可以同时发生。这意味着您的计时器必须是线程安全的。
除了以外的UI计时器类(WinForms / WPF)。他们的tick函数在UI线程上运行。使用DoEvents
,即使存在另一个避免DoEvents
的原因,也可能导致重入。
答案 1 :(得分:1)
从处理程序的名称我假设您使用的是System.Windows.Forms.Timer,它是单线程的。这意味着Tick
事件将在前一个事件结束后触发。要打破循环,您必须在另一个线程中执行代码并使用退出条件。
这就是我通常的做法:
private bool running;
private bool restart;
private void DoWork(object item)
{
running = true;
TSM.ModelObjectEnumerator myEnum = null;
myEnum = new TSM.UI.ModelObjectSelector().GetSelectedObjects();
while (myEnum.MoveNext() && !restart)
{
//do your stuff
if (myEnum.Current != null) {....}
}
if(restart)
{
restart = false;
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (running)
restart = true;
else
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
}
答案 2 :(得分:0)
解决方法是在while事件的顶部禁用计时器,并在退出while事件时重新启用它。
答案 3 :(得分:0)
while循环不会被破坏,因为计时器再次勾选。但无论如何,最好的办法是在事件处理程序的开头禁用计时器,并在最后重新启用它。
答案 4 :(得分:0)
你总是可以尝试类似的东西,这样你就可以让多个计时器勾选并启动进程。写在记事本中,请原谅任何大规模的拼写错误
private Timer _systemTimer = null;
public MyApp()
{
_systemTimer = new Timer("how ever you set your 1 second);
// Create your event handler for when it ticks over
_systemTimer.Elapsed += new ElapsedEventHandler(systemTimerElapsed);
}
protected void systemTimerElapsed(object sender, ElapsedEventArgs e)
{
_systemTimer.Stop();
//Do what you need to do
_systemTimer.Start();
//This way if it takes longer than a second it won't matter, another time won't kick off until the previous job is done
}
答案 5 :(得分:0)
我会让你很容易;在另一个后台线程中使用Thread.Sleep()并完成它!
如果您知道何时完成,只需使用AutoResetEvent来保持线程同步。 如果您对更新没有任何控制没有回调,时间未知我建议增加您的计时器间隔!
var thread = new Thread((ThreadStart)delegate
{
While(true)
{
TSM.ModelObjectEnumerator myEnum = null;
myEnum = new TSM.UI.ModelObjectSelector().GetSelectedObjects();
while (myEnum.MoveNext())
{
if (myEnum.Current != null)
{....}
}
Thread.Sleep(1000);
}
}
thread.Start();
答案 6 :(得分:0)
从txtString中获取字符串中的每个char,并使用timerControl
逐个写入标签int g = 0;
private void timerString_Tick(object sender, EventArgs e)
{
string a = txtString.Text;
int em = txtString.TextLength;
if (g < em)
{
lblString.Text = lblString.Text + a[g];
g++;
}
else timerString.Stop();
}
来自
private void btnStringStart_Click(object sender, EventArgs e)
{
timerString.Start();
lblString.Text = "";
}