/// <summary> /// Schedules a periodic piece of work on the message loop associated with the control, using a Windows Forms Timer object. /// </summary> /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam> /// <param name="state">Initial state passed to the action upon the first iteration.</param> /// <param name="period">Period for running the work periodically.</param> /// <param name="action">Action to be executed, potentially updating the state.</param> /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns> /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="period"/> is less than one millisecond.</exception> public IDisposable SchedulePeriodic <TState>(TState state, TimeSpan period, Func <TState, TState> action) { // // Threshold derived from Interval property setter in ndp\fx\src\winforms\managed\system\winforms\Timer.cs. // if (period.TotalMilliseconds < 1) { throw new ArgumentOutOfRangeException(nameof(period)); } if (action == null) { throw new ArgumentNullException(nameof(action)); } var createTimer = new Func <IScheduler, TState, IDisposable>((scheduler1, state1) => { var timer = new Windows.Forms.Timer(); timer.Tick += (s, e) => { if (!_control.IsDisposed) { state1 = action(state1); } }; timer.Interval = (int)period.TotalMilliseconds; timer.Start(); return(Disposable.Create(() => { var t = Interlocked.Exchange(ref timer, null); if (t != null) { t.Stop(); action = _ => _; } })); }); // // This check is critical. When creating and enabling a Timer object on another thread than // the UI thread, it won't fire. // if (_control.InvokeRequired) { return(Schedule(state, createTimer)); } else { return(createTimer(this, state)); } }
public event TickEventHandler Tick; // Implements ITimer.Tick ' Declare the tick event /// <summary> /// ''' Create a new timer component /// ''' </summary> /// ''' <remarks></remarks> public SurroundingClass() { TL = new TraceLogger("", "Timer"); TraceEnabled = GetBool(TRACE_TIMER, TRACE_TIMER_DEFAULT); TL.Enabled = TraceEnabled; TL.LogMessage("New", "Started on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()); FormTimer = new Windows.Forms.Timer(); TL.LogMessage("New", "Created FormTimer"); FormTimer.Enabled = false; // Default settings FormTimer.Interval = 1000; // Inital period - 1 second TL.LogMessage("New", "Set FormTimer interval"); TimersTimer = new System.Timers.Timer(); TL.LogMessage("New", "Created TimersTimer"); TimersTimer.Enabled = false; // Default settings TimersTimer.Interval = 1000; // Inital period - 1 second TL.LogMessage("New", "Set TimersTimer interval"); try { TL.LogMessage("New", "Process FileName " + "\"" + Process.GetCurrentProcess().MainModule.FileName + "\""); PEReader PE = new PEReader(Process.GetCurrentProcess().MainModule.FileName, TL); TL.LogMessage("New", "SubSystem " + PE.SubSystem.ToString); switch (PE.SubSystem) { case object _ when PEReader.SubSystemType.WINDOWS_GUI // Windows GUI app : { IsForm = true; break; } case object _ when PEReader.SubSystemType.WINDOWS_CUI // Windows Console app : { IsForm = false; break; } default: { IsForm = false; break; } } // If Process.GetCurrentProcess.MainModule.FileName.ToUpper.Contains("WSCRIPT.EXE") Then 'WScript is an exception that is marked GUI but behaves like console! // TL.LogMessage("New", "WScript.Exe found - Overriding IsForm to: False") // IsForm = False // End If // If Process.GetCurrentProcess.MainModule.FileName.ToUpper.Contains("ASTROART.EXE") Then 'WScript is an exception that is marked GUI but behaves like console! // TL.LogMessage("New", "AstroArt.Exe found - Overriding IsForm to: False") // IsForm = False // End If IsForm = !ForceTimer(IsForm); // Override the value of isform if required TL.LogMessage("New", "IsForm: " + IsForm); } catch (Exception ex) { TL.LogMessageCrLf("New Exception", ex.ToString()); // Log error and record in the event log LogEvent("Timer:New", "Exception", EventLogEntryType.Error, EventLogErrors.TimerSetupException, ex.ToString()); } }
/// <summary> /// Schedules an action to be executed after dueTime on the message loop associated with the control, using a Windows Forms Timer object. /// </summary> /// <typeparam name="TState">The type of the state passed to the scheduled action.</typeparam> /// <param name="state">State passed to the action to be executed.</param> /// <param name="action">Action to be executed.</param> /// <param name="dueTime">Relative time after which to execute the action.</param> /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns> /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception> public override IDisposable Schedule <TState>(TState state, TimeSpan dueTime, Func <IScheduler, TState, IDisposable> action) { if (action == null) { throw new ArgumentNullException(nameof(action)); } var dt = Scheduler.Normalize(dueTime); if (dt.Ticks == 0) { return(Schedule(state, action)); } var createTimer = new Func <IScheduler, TState, IDisposable>((scheduler1, state1) => { var d = new MultipleAssignmentDisposable(); var timer = new Windows.Forms.Timer(); timer.Tick += (s, e) => { var t = Interlocked.Exchange(ref timer, null); if (t != null) { try { if (!_control.IsDisposed && !d.IsDisposed) { d.Disposable = action(scheduler1, state1); } } finally { t.Stop(); action = null; } } }; timer.Interval = (int)dt.TotalMilliseconds; timer.Start(); d.Disposable = Disposable.Create(() => { var t = Interlocked.Exchange(ref timer, null); if (t != null) { t.Stop(); action = (_, __) => Disposable.Empty; } }); return(d); }); // // This check is critical. When creating and enabling a Timer object on another thread than // the UI thread, it won't fire. // if (_control.InvokeRequired) { return(Schedule(state, createTimer)); } else { return(createTimer(this, state)); } }