2011-11-08 19 views
0

處理的System.Threading定時器事件中,我創建了每下面的代碼計時器事件處理程序的類對象:如何在WPF

public class MyTimerClass 
    { 
     private Timer _timeoutTimer; 

     private void Constructor() 
     { 
      _timeoutTimer = new Timer(TimerHandler, null, 0, 1000); 
     } 

     private void TimerHandler() 
     { 
      if (Something) 
       LogMessage(LogLevel.Error, "Timeout Waiting..."); 
     } 
    } 

我在同一個類的對象創建LogMessageHandler事件與委託處理定時器事件和其他日誌事件:

public delegate void LogMessageHandler(LogLevel logLevel, string message); 
    public event LogMessageHandler OnLogMessage; 

    private void LogMessage(LogLevel logLevel, string message) 
    { 
     if (OnLogMessage != null) 
     OnLogMessage(logLevel, message); 
    } 

在另一個類中,我想處理爲定時器派生的日誌消息。這是我訂閱的OnLogMessage事件和處理線程類:

 void InitializeMyTimerClass() 
     { 
      try 
      { 
       _myTimerClass = new MyTimerClass(); 
       _myTimerClass.OnLogMessage += new LogMessageHandler(UpdateLogMessage); 
      } 
      catch (Exception ex) 
      { 
       _dialog.ShowException(ex.Message); 
      } 
     } 

     private void UpdateLogMessage(LogLevel newLogLevel, string message) 
     { 
      TaskScheduler schedulerForLog = TaskScheduler.FromCurrentSynchronizationContext(); 

      Task.Factory.StartNew(() => TrackResponseMessage.Add(FormatLogLevelToString(newLogLevel) + ": " + message), 
      CancellationToken.None, TaskCreationOptions.None, schedulerForLog); 
     } 

當我運行的代碼和定時器事件發生時,我把其中的TaskScheduler創建一個斷點:的TaskScheduler schedulerForLog =的TaskScheduler。 FromCurrentSynchronizationContext(); LogLevel和字符串參數已成功從MyTimerClass傳遞。但是,當TaskScheduler嘗試獲取當前同步上下文時,我得到一個InvalidOperationException。它看起來來自計時器線程的SynchronizationContext對於TaskScheduler來說是不可接受的。

問:定時器事件是否在單獨的線程中傳遞?在這種情況下處理計時器線程的最佳方法是什麼?有人可以提供演示代碼嗎? ...謝謝!

回答

2

如果你的問題是一個跨線程操作無效,可以使用Application.Current.Dispatcher調用要在應用程序的主線程運行過程中要避免的問題:

private void UpdateLogMessage(LogLevel newLogLevel, string message) 
    { 
     Application.Current.Dispatcher.BeginInvoke(new Action(()=>{ 
      TaskScheduler schedulerForLog = TaskScheduler.FromCurrentSynchronizationContext(); 

      Task.Factory.StartNew(() => TrackResponseMessage.Add(FormatLogLevelToString(newLogLevel) + ": " + message), 
      CancellationToken.None, TaskCreationOptions.None, schedulerForLog); 
     }); 
    } 

如果主線程不是你需要的線程,那麼你需要爲你想要的線程保存調度程序,並從那裏調用線程。