一、前言
对于多线程实时监控控件,其实现原理无外乎另开一个线程每隔一定时间进行实时监控。大多是使用
Timer控件,而system.windows.forms.timer则是主线程执行的,故不能实现。
二、.NET提三种记时器
1,System.Timers.Timer:
这个Timer是使用线程池中的线程去执行任务的,可以指定线程池中的某个线程去执行任务。
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系
结构,因此基于服务器的计时器可能比Windows 计时器精确得多。服务器计时器可以在线程之间移动来
处理引发的事件。
2,System.Threading.Timer:
和1中的Timer类似也是使用线程池中的线程去执行任务的,但是不可以指定线程池中的某个线程去
执行任务。
特点:使用imerCallback委托指定希望Timer执行的方法。此方法不在创建计时器的线程中执行,
而是在系统提供的线程池线程中执行。
3,System.Windows.Forms.Timer:
该Timer的特点是执行任务的线程是专属于任务相关窗口的。决不能用这个Timer执行时间太长(例
如几分之一秒)的任务,否则会造成界面无响应。
特点:计时器是为单线程环境设计的,其中,UI线程用于执行处理。Windows 计时器的精度限定
为55毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或
者将调用封送到另一个线程。
三、实现
使用System.Threading.Timer,另开线程进行控制。如下:下面代码功能为,实现紧急案件的实时
检测,并发现案件是,提醒处理,其中包括提醒处理等操作均不影响主线程的运行,这是要达到的目标
。
private EnumDoingFlag m_EnumDoingFlag = EnumDoingFlag.EnumDoingFlagNone;
private System.Threading.Timer m_Timer;
public void StartMonitor()
{
System.Threading.TimerCallback pTimerCallback = new
System.Threading.TimerCallback(m_Timer_OnTickerEvent);
m_Timer = new System.Threading.Timer(pTimerCallback, null, m_DueTime,
m_Interval);
m_EnumDoingFlag = EnumDoingFlag.EnumDoingFlagDoing;
}
public void StopMonitor()
{
m_Timer.Dispose();
m_EnumDoingFlag = EnumDoingFlag.EnumDoingFlagNone;
this.m_dictEvent.Clear();
}
private IDictionary<string, bool> m_dictEvent = new Dictionary<string, bool>();//案
件ID,是否已经提醒
private void m_Timer_OnTickerEvent(object obj)
{
try
{
Event[] arrayEvent = this.m_Services.getExigence
(JinpengGIS.UserClass.UserInfo.userId, "" , "", "");
if (arrayEvent == null || (arrayEvent.Length == 1 && arrayEvent[0] ==
null))
return;
IList<Event> listEvent = new List<Event>();
for (int i = 0; i < arrayEvent.Length; i++)
{
if (this.m_dictEvent.ContainsKey(arrayEvent[i].eventId) &&
this.m_dictEvent[arrayEvent[i].eventId] == true)
continue;
else
{
listEvent.Add(arrayEvent[i]);
this.m_dictEvent[arrayEvent[i].eventId] = true;
}
}
Event[] arrayEvent2 = new Event[listEvent.Count];
listEvent.CopyTo(arrayEvent2, 0);
if (listEvent.Count != 0)
this.ThreadAssitant(arrayEvent2);
}
catch
{
return;
}
}
private delegate void ThreadAssitantHandler(Event[] events);
private void ThreadAssitant(Event[] events)
{
if (this.InvokeRequired)
{
ThreadAssitantHandler pThreadAssitantHandler = new ThreadAssitantHandler
(this.ThreadAssitant);
this.Invoke(pThreadAssitantHandler, new object[] { events });
}
else
{
TaskbarNotifierMonitorHelper pTaskbarNotifierMonitorHelper = new
TaskbarNotifierMonitorHelper();
pTaskbarNotifierMonitorHelper.TaskbarNotifierMonitor.ListBox.MouseDoubleClick += new
MouseEventHandler(ListBox_MouseDoubleClick);
pTaskbarNotifierMonitorHelper.TaskbarNotifierMonitor.EventbtnOk_Click +=
new EventHandler(TaskbarNotifierMonitor_EventbtnOk_Click);
pTaskbarNotifierMonitorHelper.ShowNotifier("紧急案件", "请尽快处理", 0,
events);
}
}
四、注意事项
(1)对于多线程实时监控控件MonitorService必须继承与基类Form,而不能继承与Control或
UserControl。因为如果继承至Control或UserControl则只有在添加到Form且Show后在可用,否则无法刷
新。
(2)为例在使用代码实例化时能够实现触发的刷新,需要在构造函数中先把控件显示再隐藏,做如下
处理。
//解决刷新问题
base.Width = 1;
base.Height = 1;
base.WindowState = FormWindowState.Minimized;
base.ShowInTaskbar = false;
base.Show();
base.Hide();
五、总结
对于多线程实时监控的控件实现原理大抵如此,变换可实现不同的应用。