做了System.Timers.Timer经过上比创建它的线程一个单独的线程?
可以说,我有一个类与每5秒触发一个计时器。 当计时器触发,在经过的方法,一些对象被修改。 可以说,这需要很长的时间来修改这个对象,比如10秒。 是否有可能,我会在这种情况下碰上线程冲突?
做了System.Timers.Timer经过上比创建它的线程一个单独的线程?
可以说,我有一个类与每5秒触发一个计时器。 当计时器触发,在经过的方法,一些对象被修改。 可以说,这需要很长的时间来修改这个对象,比如10秒。 是否有可能,我会在这种情况下碰上线程冲突?
对于System.Timers.Timer :
请参见下面的布赖恩·基甸的答案
对于System.Threading.Timer :
关于定时器MSDN文档指出:
该System.Threading.Timer类使得在一个线程池线程回调并不会在所有使用的事件模型。
因此,我们确实在定时器结束在不同的线程。
这取决于。 该System.Timers.Timer
有两种操作模式。
如果SynchronizingObject
设置为ISynchronizeInvoke
实例,然后将Elapsed
事件将在托管同步对象的线程上。 通常这些ISynchronizeInvoke
情况下是没有比普通的老式其他Control
和Form
大家都熟悉的例子。 因此,在这种情况下, Elapsed
事件调用UI线程上和它的行为类似于System.Windows.Forms.Timer
。 否则,它真的取决于具体ISynchronizeInvoke
使用该实例。
如果SynchronizingObject
为null,则Elapsed
事件上调用一个ThreadPool
线程,它的行为类似System.Threading.Timer
。 事实上,它实际上采用的是System.Threading.Timer
幕后,如果需要,它接收到的计时器回调之后做编排操作。
每个经过的事件将触发在同一个线程,除非先前已用仍在运行。
因此,它可以为您处理碰撞
尝试把这个在控制台
static void Main(string[] args)
{
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
var timer = new Timer(1000);
timer.Elapsed += timer_Elapsed;
timer.Start();
Console.ReadLine();
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Thread.Sleep(2000);
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
你会得到这样的事情
10
6
12
6
12
其中10是调用线程和6和12从BG经过事件触发。 如果删除了Thread.Sleep(2000); 你会得到这样的事情
10
6
6
6
6
由于没有冲突。
但是,这仍然让ü一个问题。 如果u是触发事件每隔5秒,它需要10秒编辑u需要一些锁定跳过一些编辑。
对于System.Timers.Timer,在单独的线程,如果是对于SynchronizingObject没有设置。
static System.Timers.Timer DummyTimer = null;
static void Main(string[] args)
{
try
{
Console.WriteLine("Main Thread Id: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
DummyTimer = new System.Timers.Timer(1000 * 5); // 5 sec interval
DummyTimer.Enabled = true;
DummyTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnDummyTimerFired);
DummyTimer.AutoReset = true;
DummyTimer.Start();
Console.WriteLine("Hit any key to exit");
Console.ReadLine();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
return;
}
static void OnDummyTimerFired(object Sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
return;
}
输出你会看到,如果DummyTimer 5秒的间隔发射:
Main Thread Id: 9
12
12
12
12
12
...
所以,正如所见,OnDummyTimerFired是在工人线程中执行。
不,更复杂的 - 如果减少间隔说10毫秒,
Main Thread Id: 9
11
13
12
22
17
...
这是因为,如果在接下来的蜱被激发不这样做OnDummyTimerFired的分组执行,那么.NET将创建一个新的线程来完成这项工作。
更为复杂的事情,“该System.Timers.Timer类提供了一个简单的方法来解决这一难题,它暴露了一个公共属性SynchronizingObject的。这个属性设置为Windows窗体(或Windows窗体上的控制)的实例将确保在你经过的事件处理程序代码在其上用SynchronizingObject的实例化的同一个线程上运行“。
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S2
另一方面,在经过事件需要更长的时间,然后间隔,它会创建另一个线程来提高所经过的事件。 但对于这个解决方法
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
timer.Stop();
Thread.Sleep(2000);
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
finally
{
timer.Start();
}
}