Bugzilla – Attachment 170526 Details for
Bug 322163
runtime hangs after main() exit
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Forgot Password
c# code
Program.cs (text/plain), 6.92 KB, created by
Thomas Wiest
on 2006-10-06 21:00:00 UTC
(
hide
)
Description:
c# code
Filename:
MIME Type:
Creator:
Thomas Wiest
Created:
2006-10-06 21:00:00 UTC
Size:
6.92 KB
patch
obsolete
>using System; >using System.Collections.Generic; >using System.Text; >using System.ComponentModel; >using System.Threading; > >namespace TimersBug >{ > > // The reason why this program hangs sometimes after returning from main seems like threads are alive > // and running after we return from main. But the CLR should not hang or crash and be able to kill > // the threads > class Program > { > static Timer t1, t2, t3, t4; > static void Main(string[] args) > { > t1 = new Timer(); > t1.Elapsed += new ElapsedEventHandler(t1_Elapsed); > t1.Interval = 100; > t1.Start(); > > t2 = new Timer(); > t2.Elapsed += new ElapsedEventHandler(t2_Elapsed); > t2.Interval = 300; > t2.Start(); > > t3 = new Timer(); > t3.Elapsed += new ElapsedEventHandler(t3_Elapsed); > t3.Interval = 150; > t3.Start(); > > t4 = new Timer(); > t4.Elapsed += new ElapsedEventHandler(t4_Elapsed); > t4.Interval = 250; > t4.Start(); > > Console.WriteLine("Hit Return To Exit..."); > Console.ReadLine(); > } > > > static void t4_Elapsed(object sender, ElapsedEventArgs e) > { > Console.WriteLine("Got Event T4"); > } > > static void t3_Elapsed(object sender, ElapsedEventArgs e) > { > Console.WriteLine("Got Event T3"); > } > > static void t2_Elapsed(object sender, ElapsedEventArgs e) > { > Console.WriteLine("Got Event T2"); > } > > static void t1_Elapsed(object sender, ElapsedEventArgs e) > { > Console.WriteLine("Got Event T1"); > } > } > > > > #region System.Timers.Timer >#pragma warning disable 1591 > > public class ElapsedEventArgs : EventArgs > { > DateTime time; > > internal ElapsedEventArgs(DateTime time) > { > this.time = time; > } > > public DateTime SignalTime > { > get { return time; } > } > } > > public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e); > > public class Timer : Component, ISupportInitialize > { > bool _autoReset; > bool _enabled; > double _interval; > ISynchronizeInvoke _so; > ManualResetEvent _intervalTimer; > AutoResetEvent _stopTimer; > AutoResetEvent _quitThread; > Thread _thread; > > public event ElapsedEventHandler Elapsed; > > public Timer() > : this(100) > { > } > > public Timer(double interval) > { > _autoReset = true; > _enabled = false; > Interval = interval; > _so = null; > _intervalTimer = new ManualResetEvent(false); > _stopTimer = new AutoResetEvent(false); > _quitThread = new AutoResetEvent(false); > } > > > public bool AutoReset > { > get { return _autoReset; } > set { _autoReset = value; } > } > > public bool Enabled > { > get { return _enabled; } > set > { > if (_enabled == value) > return; > > _enabled = value; > if (value) { > if (_thread == null) { > _thread = new Thread(new ThreadStart(StartTimer)); > _thread.IsBackground = true; > _thread.Start(); > } > // get it out of the loop > _stopTimer.Set(); > } > else { > StopTimer(); > } > } > } > > public double Interval > { > get { return _interval; } > set > { > // The doc says 'less than 0', but 0 also throws the exception > if (value <= 0) > throw new ArgumentException("Invalid value: " + _interval, "interval"); > > _interval = value; > } > } > > public override ISite Site > { > get { return base.Site; } > set { base.Site = value; } > } > > public ISynchronizeInvoke SynchronizingObject > { > get { return _so; } > set { _so = value; } > } > > public void BeginInit() > { > // Nothing to do > } > > public void Close() > { > Enabled = false; > _quitThread.Set(); > } > > public void EndInit() > { > // Nothing to do > } > > public void Start() > { > Enabled = true; > } > > public void Stop() > { > Enabled = false; > } > > protected override void Dispose(bool disposing) > { > Close(); > base.Dispose(disposing); > } > > static void Callback(object state) > { > Timer timer = (Timer)state; > if (timer.Elapsed == null) > return; > > ElapsedEventArgs arg = new ElapsedEventArgs(DateTime.Now); > > if (timer._so != null && timer._so.InvokeRequired) { > timer._so.BeginInvoke(timer.Elapsed, new object[2] { timer, arg }); > } > else { > timer.Elapsed(timer, arg); > } > } > > void StartTimer() > { > WaitCallback wc = new WaitCallback(Callback); > WaitHandle[] handlesToWaitOn = new WaitHandle[3]; > handlesToWaitOn[0] = _quitThread; > handlesToWaitOn[1] = _stopTimer; > handlesToWaitOn[2] = _intervalTimer; > > while (true) { > int myInterval = (int)_interval; > if (_enabled == false) { > myInterval = 10000000; > } > > int ret = WaitHandle.WaitAny(handlesToWaitOn, myInterval, false); > if (ret == 0) { > // quit thread > Console.WriteLine("got quit thread"); > break; > } > else if (ret == 1) { > // someone stopped the timer > Console.WriteLine("got stop timer"); > } > else { > Console.WriteLine("got interval timer:" + myInterval.ToString()); > if (_enabled) { > if (_autoReset == false) { > _enabled = false; > } > ThreadPool.QueueUserWorkItem(wc, this); > } > } > } > wc = null; > } > > void StopTimer() > { > _stopTimer.Set(); > } > } >#pragma warning restore 1591 > #endregion > >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
Attachments on
bug 322163
: 170526 |
170527