开发者

Undesired termination of Thread created in Timer callback

This is what I want to do:

  1. Have a timer with some interval
  2. In the timer callback code, if some condition is met, another thread should be run

I’ve put my code in a class which is instantiated by the main form and the code is executed upon method call (‘StartSync()’, se sample code).

The problem is that the code runs for a couple of seconds but then terminates. I suppose I’m doing something stupid but I really can’t see what it is. Thankful for any help with regards to this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
    class Syncer
    {
        static bool SYNC_IN_PROGRESS;

        public void StartSync()
        {
            SYNC_IN_PROGRESS = false;
            Timer timer = new Timer(timerCallback, null, 0, 1000);
        }

        public void timerCallback(Object stateInfo)
        {
            Debug.WriteLine("Sync?");

            if (!SYNC_IN_PROGRESS)
            {
                SYNC_IN_PROGRESS = true;

                Thread thSync = new Thread(new T开发者_JAVA百科hreadStart(sync));
                thSync.Start();
            }
        }

        void sync()
        {
            Debug.WriteLine("Syncing...");
            SYNC_IN_PROGRESS = false;
        }
    }
}


At a guess, the Timer is only held in a method variable; it sounds to me like the Timer is getting garbage collected and finalized, hence terminated. I suspect you should hold onto that reference in a field to prevent collection.

As an aside - I doubt it is the cause here, but when dealing with threading you should be religiously aware of access to shared state from multiple threads; for example:

  • using Monitor (aka lock)
  • appropriate use of volatile
  • Interlocked when it fits

Your current access to the static bool will probably work OK, but...


Try this cleaner approach

    static volatile bool SYNC_IN_PROGRESS; 
    static thread syncPoll; 

    public void StartSync() 
    { 
        SYNC_IN_PROGRESS = false; 
        syncPoll = new Thread(sync);
        syncPoll.Start();
    } 

    void sync() 
    { 
        while (true)
        {
             Debug.WriteLine("Sync?");
             if (SYNC_IN_PROGRESS) Debug.WriteLine("Syncing..."); 
             Thread.Sleep(1000);
        }
    } 

It does the same you try to do with your current code :) but doesn't use a timer


So here is what I did and it seems to work just fine

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            StartSync();
        }

        static bool SYNC_IN_PROGRESS;

        public void StartSync()
        {
            SYNC_IN_PROGRESS = false;
            System.Threading.Timer timer = new System.Threading.Timer(timerCallback, SYNC_IN_PROGRESS, 0, 1000); 


        }

        public void timerCallback(Object stateInfo)
        {
            Debug.WriteLine("Sync?");

            if (!(bool)stateInfo)
            {
                SYNC_IN_PROGRESS = true;

                Thread thSync = new Thread(new ThreadStart(sync));
                thSync.Start();
            }
        }

        void sync()
        {
            Debug.WriteLine("Syncing...");
            SYNC_IN_PROGRESS = false;
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜