简体   繁体   中英

C# restarting Threading.Timer with Change does not stop initial Timer instance

Good day.

My question is a follow-up (of sorts) to this post: Resetting Threading Timer if it's called a second time

I've tried the suggestions there, and it partially solved my problem.

I have a C# application that contains four Threading.Timers. this is how I designed them:

Summary: two threads run every 2 hours, one thread runs only once, one thread runs every minute. All four threads post updates to a ListBox (lstMonitor). I also have a button that clears lstMonitor, and should restart all four Threads.

public partial class FullSynchro : Form
{
    public System.Threading.Timer TimerReference;
    public bool TimerCanceled;

    readonly TimeSpan tsTwo = new TimeSpan(2, 0, 0);

    TimeSpan tickTwo = new TimeSpan(2, 0, 0);
    TimeSpan tickOne = new TimeSpan(2, 0, 0);

    readonly TimeSpan tsFour = new TimeSpan(0, 1, 0);
    TimeSpan tickFour = new TimeSpan(0, 1, 0);

    System.Threading.Timer thSyncTwo, thSyncOne, thSyncThree, thSyncFour;

    public delegate void InvokeDelegate(string input);

    FullSynchro objOne, objTwo, objThree, objFour;
    TimerCallback tcbOne, tcbTwo, tcbThree, tcbFour;

    public FullSynchro()
    {
        InitializeComponent();
    }

    private void FullSynchro_Load(object sender, EventArgs e)
    {
        /* instantiating the class that gets called by the Timer. */
        objOne = new FullSynchro();
        tcbOne = new TimerCallback(PerformSyncOne);

        /* instantiate the Timer object */
        thSyncOne = new System.Threading.Timer(tcbOne, objOne, 0, Timeout.Infinite);
        objOne.TimerReference = thSyncOne;

        objTwo = new FullSynchro();
        tcbTwo = new TimerCallback(PerformSyncTwo);
        thSyncTwo = new System.Threading.Timer(tcbTwo, objTwo, 0, Timeout.Infinite);
        objTwo.TimerReference = thSyncTwo;

        /* one-time Sync */
        objThree = new FullSynchro();
        tcbThree = new TimerCallback(PerformSyncThree);
        thSyncThree = new System.Threading.Timer(tcbThree, objThree, 0, 0);
        objThree.TimerReference = thSyncThree;

        objFour = new FullSynchro();
        tcbFour = new TimerCallback(PerformSyncFour);
        thSyncFour = new System.Threading.Timer(tcbFour, objFour, 0, Timeout.Infinite);
        objFour.TimerReference = thSyncFour;
    }

        void PerformSyncOne(object StateObj)
        {
            //code goes here
        }

        void PerformSyncTwo(object StateObj)
        {
            //code goes here
        }

        void PerformSyncThree(object StateObj)
        {
            //code goes here
        }

        void PerformSyncFour(object StateObj)
        {
            //code goes here
        }

    private void btnOverride_Click(object sender, EventArgs e)
    {
        if (Message.Show("Are you sure you wish to restart Sync?", this.Text) == DialogResult.Yes)
        {
            thSyncTwo.Change(0, 0);

            //lstMonitor.Items.Clear();
            //PerformSync();
        }
    }
}

The button code kinda worked; thSyncTwo.Change() did execute PerformSyncTwo() from the start, but the first instance of PerformSyncTwo() still kept on posting updates to lstMonitor.

I've read about using WaitHandle , but I can't make it work. I tried using Dispose() on almost everything thread-related in my code, but the first instance of the Timer still kept on running. I really need to "kill" the previous instances of those Timers, then "resurrect" them.

So, is it possible? Or should I use a different kind of Timer?

If you would like to stop timer you can use timer.Change(Timeout.Infinite, Timeout.Infinite) It's works and stops timer without disposing. After that you should invoke .Change() with proper values to start the timer again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM