the Timer in my VSTO addin is only being fired once or twice

时间:2016-07-11 19:35:45

标签: c# timer vsto

I have built a VSTO addin for Outlook. I have implemented a timer to "refresh" the pane at specified intervals. When I run it directly from Visual Studio (i.e., from the Debugger), it works fine (the timer callback is called every 30 seconds). But when I publish the solution and install it, the timer is called once (or sometimes twice) and never again. Here is a snippet of my code

using System.Threading;
using ThreadedTimer = System.Threading.Timer;

namespace Outlook2013TodoAddIn  
{
    public partial class AppointmentsControl : UserControl
    {
        public AppointmentsControl()
        {
            InitializeComponent(); 
            InitializeRefhreshTimer();  
            this.textBox1.Text = "0";
        }

        private void InitializeRefhreshTimer()
        {
            TimerCallback timerDelegate =
               new TimerCallback(refreshTimer_Tick);

            TimeSpan refreshIntervalTime = 
                new TimeSpan(0, 0, 0, 30, 1000); //every 30 seconds 
            ThreadedTimer refreshTimer = 
                new ThreadedTimer(timerDelegate, null, TimeSpan.Zero, refreshIntervalTime);
        }

        public void refreshTimer_Tick(Object stateInfo)
        {
            if (InvokeRequired)
            {
                this.BeginInvoke(new MethodInvoker(delegate
                {
                    this.textBox1.Text = 
                        (Int32.Parse(this.textBox1.Text) + 1).ToString();
                }));
            }
        }       
    }
}   

What am I missing?

1 个答案:

答案 0 :(得分:2)

Ahh, I finally figured it out. I found the following comment buried in ch. 27 of Jeffrey Richter's CLR via C#:

When a Timer object is garbage collected, its finalization code tells the thread pool to cancel the timer so that it no longer goes off. So when using a Timer object, make sure that a variable is keeping the Timer object alive or else your callback method will stop getting called.

My timer was getting gobbled up by the GC! I created a private variable in my AppointmentsControl class and that solved the problem.


What puzzles me is that the official documentation specifically prescribes the approach that I originally used. It's too bad that page doesn't allow user feedback.