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?
答案 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.