2016-07-11 34 views
0

我建立了一個VSTO加載項爲Outlook。我已經實現了一個定時器,以指定的時間間隔「刷新」窗格。當我直接從Visual Studio(即從調試器)運行它時,它工作正常(定時器回調每30秒調用一次)。但是,當我發佈解決方案並安裝它時,定時器會被調用一次(或者有時兩次),而不再一次。這裏是我的代碼片段定時器在我的VSTO插件只被解僱一次或兩次

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(); 
       })); 
      } 
     }  
    } 
} 

我在想什麼?

回答

2

啊,我終於想通了。我發現下面的評論埋在ch。傑弗裏Richter的CLR via C# 27:

當一個Timer對象進行垃圾回收,其終止代碼告訴線程池來取消計時器,使其不再熄滅。所以當使用Timer對象時,確保一個變量保持Timer對象的活性,否則你的回調方法將停止調用。

我的計時器得到由GC吞噬了!我在AppointmentsControl類中創建了一個私有變量,解決了這個問題。


讓我感到困惑的是,the official documentation明確規定了我最初使用的方法。頁面不允許用戶反饋太糟糕了。

+1

我不建議使用System.Threading.Timer對象 - 它使用輔助線程來運行定時器處理。如果您在輔助線程中訪問Outlook對象模型中的任何內容,那麼這只是麻煩,所以在這種情況下使用System.Windows.Forms.Timer。 –

+0

@EricLegault:我從Windows.Forms計時器開始,但我需要更多的靈活性。具體地講,我需要在每個小時的頂部,以觸發定時器,並根據[此篇](http://stackoverflow.com/a/4532859/93394),System.Threading.Timer是我的唯一的選擇。你能否給我一個這種選擇可能導致什麼樣的麻煩的想法? – kmote

+0

我已經解決了麻煩:輔助線程+ Outlook對象=不支持(和Outlook崩潰)。如果您在這些線程中沒有使用Outlook對象,請不要擔心 –