[英]Calling Timer Tick event after enabling timer in another class
我必須做一些完全錯誤的事情,但我無法弄清楚。 我有一個表單,我在VS中添加了一個計時器控件。 我還有一個正在監視應用程序啟動的類(notepad.exe)。 當事件到達時,它應該啟用計時器,設置間隔並在每個刻度上執行某些操作(例如觸發消息框或更改標簽)。 這似乎沒有發生。 看看代碼可以幫助別人給我一些線索。 代碼如下:
public partial class Monitor : Form
{
EventWatcher eventWatch = new EventWatcher();
ManagementEventWatcher startWatcher = new ManagementEventWatcher();
ManagementEventWatcher endWatcher = new ManagementEventWatcher();
public Monitor()
{
InitializeComponent();
startWatcher = eventWatch.WatchForProcessStart("notepad.exe");
endWatcher = eventWatch.WatchForProcessEnd("notepad.exe");
}
private void appTimer_Tick(object sender, EventArgs e)
{
label1.Text = "tick";
MessageBox.Show("Tick");
}
}
守望者課程是
class EventWatcher
{
public ManagementEventWatcher WatchForProcessStart(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 2 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessStarted;
watcher.Start();
return watcher;
}
public void ProcessStarted(object sender, EventArrivedEventArgs e)
{
Monitor monitor = new Monitor();
//set timer interval and start time for Monitor class. (form)
monitor.appTimer.Interval = 5000;
monitor.appTimer.Enabled = true;
MessageBox.Show("notepad started");
}
}
我注意到兩件事:
當notepad.exe啟動時,我有MessageBox.Show("notpad started");
line注釋掉計時器tick事件中的messabox不會觸發。 如果它如上所示,它將顯示兩個消息框(記事本開始和勾選)。 但是,無論如何, label1.Text
都不會改變。
我不確定我做錯了什么。 我確信它與如何處理計時器事件有關,但我不確定我應該做什么。 有任何想法嗎?
您的代碼創建了一個新的Monitor實例。 因此,您不會訪問名為eventWatch.WaitForProcessStart()的Monitor實例的屬性,因此它們不會更改。 解決此問題的一種方法是在觸發ProcessStarted()時觸發事件。 您的代碼可能如下所示:
class EventWatcher
{
public event EventHandler<EventArrivedEventArgs> ProcessStarted;
public ManagementEventWatcher WatchForProcessStart(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 2 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += OnProcessStarted;
watcher.Start();
return watcher;
}
protected virtual void OnProcessStarted(object sender, EventArrivedEventArgs e)
{
EventHandler<EventArrivedEventArgs> copy = ProcessStarted;
if (copy != null)
copy(sender, e); // fire the event
}
}
public partial class Monitor : Form
{
EventWatcher eventWatch = new EventWatcher();
ManagementEventWatcher startWatcher = new ManagementEventWatcher();
ManagementEventWatcher endWatcher = new ManagementEventWatcher();
public Monitor()
{
InitializeComponent();
startWatcher = eventWatch.WatchForProcessStart("notepad.exe");
startWatcher.ProcessStarted += startWatcher_ProcessStarted; // subscribe to the event
endWatcher = eventWatch.WatchForProcessEnd("notepad.exe");
}
private void startWatcher_ProcessStarted(object sender, EventArrivedEventArgs e)
{
Monitor monitor = new Monitor();
//set timer interval and start time for Monitor class. (form)
monitor.appTimer.Interval = 5000;
monitor.appTimer.Enabled = true;
MessageBox.Show("notepad started");
}
private void appTimer_Tick(object sender, EventArgs e)
{
label1.Text = "tick";
MessageBox.Show("Tick");
}
}
它看起來像label1.Text
不會因為從另一個線程運行而改變。 您需要在該標簽上運行調用以從ManagementEventWatcher
更新它。
使用這個類:
using System;
using System.Windows.Forms;
public static class ControlExtensions
{
/// <summary>
/// Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
/// </summary>
/// <param name="control"></param>
/// <param name="code"></param>
public static void UIThread(this Control @this, Action code)
{
if (@this.InvokeRequired)
{
@this.BeginInvoke(code);
}
else
{
code.Invoke();
}
}
}
and replace `label1.Text = "tick" ` with
this.UIThread(() => this.label1.Text = "tick"));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.