我根据以下代码在类对象中创建了一个Timer事件处理程序。:
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是不可接受的。
问题:计时器事件是否在单独的线程中传递?在这种情况下,处理计时器线程的最佳方法是什么?有人可以提供演示代码吗? ...谢谢!
答案 0 :(得分: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);
});
}
如果主线程不是您需要的线程,那么您需要保留所需线程的调度程序并从那里调用。