C#的事件、委托测试(一) http://47.98.154.65/?id=1853
C#的事件、委托测试(二) http://47.98.154.65/?id=1854
C#的事件、委托测试(三) http://47.98.154.65/?id=1820
来个例题。
目标:
在列表框选择要监控的线程,点start后开始监控。
当这个线程结束了(比如那个记事本程序被我关闭了),弹出一个messagebox,显示信息。

然后我提供基本功能代码:
//将进程名字添加到combox中.
var processes = Process.GetProcesses();
foreach (var process in processes)
{
processComboBox.Items.Add(process.ProcessName.ToString());
}
//检查进程的方法
private void CheckProcess()
{
bool flag = true;
do
{
var processes = Process.GetProcesses();
int count = 0;
foreach (var process in processes)
{
if (string.Compare(process.ProcessName, processComboBox.Text, true) == 0)
{
count++;
}
}
if (count == 0)
{
//这里表示指定线程结束了。
flag = false;
}
} while (flag);
}好了,可以开始答题了。
下面是网上的答案:
缺点有几点 :
点击监控后,ui失去响应。
事件没有按.net规范来书写
没有实现取消监控
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//将进程名字添加到combox中.
var processes = Process.GetProcesses();
foreach (var process in processes)
{
processComboBox.Items.Add(process.ProcessName.ToString());
}
}
//启动监视方法.
private void startButton_Click(object sender, EventArgs e)
{
//4.注册监视器
ProcessExit += new ProcessMonitor(ProExit);
CheckProcess();
}
//检查进程的方法
private void CheckProcess()
{
bool flag = true;
do
{
var processes = Process.GetProcesses();
int count = 0;
foreach (var process in processes)
{
if (string.Compare(process.ProcessName, processComboBox.Text, true) == 0)
{
count++;
}
}
if (count == 0)
{
//5.The event appears.
ProcessExit(this, new EventArgs());
flag = false;
}
} while (flag);
}
//1.进程监视委托
public delegate void ProcessMonitor(object sender, EventArgs strEventArg);
//2.封装委托的事件
public event ProcessMonitor ProcessExit;
//3.委托调用的方法
private void ProExit(object sender, EventArgs strEventArg)
{
MessageBox.Show("The target process has been dispeared.");
}
}
}下面是勇哥的答卷源码:
UI响应的问题使用异步实现 。
下面三句放在“监控”按钮里面,是因为:
取消监控再监控的需要
CancellationTokenSource每次使用前需要重新new
cts = new CancellationTokenSource(); pm = new ProcessMonitor(cts); pm.processed += dispMsg;
源码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private ProcessMonitor pm;
private CancellationTokenSource cts;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Process.Start("notepad.exe");
var processes = Process.GetProcesses();
var res = processes.Where((s) => s.ProcessName == "notepad");
if (res.Count() > 0) cboProcess.Items.Add(res.ToArray()[0].ProcessName);
}
private void dispMsg(object sender, ProcessMonitor.processEventArgs e)
{
var obj = sender as ProcessMonitor;
MessageBox.Show($"线程[{obj.processName}]已经退出了!");
}
private async void butMonitor_Click(object sender, EventArgs e)
{
if (cboProcess.Text.Length < 1) return;
cts = new CancellationTokenSource();
pm = new ProcessMonitor(cts);
pm.processed += dispMsg;
//监控
var res=await pm.CheckProcess(cboProcess.Text);
}
private void butNoMonitor_Click(object sender, EventArgs e)
{
//取消监控
cts.Cancel();
pm.processed -= dispMsg;
}
}
public class ProcessMonitor
{
private CancellationTokenSource cts;
public delegate void processEventHandle(object sender, processEventArgs e);
public event processEventHandle processed;
public string processName = "";
public ProcessMonitor(CancellationTokenSource cts)
{
this.cts = cts;
}
public class processEventArgs:EventArgs
{
public bool isEnd = false;
public processEventArgs(bool isend)
{
this.isEnd = isend;
}
}
public virtual void OnProcess(processEventArgs e)
{
if (null != e)
processed(this, e);
}
public Task<bool> CheckProcess(string proName)
{
return Task.Run(() =>
{
bool flag = true;
processName = proName;
do
{
if (cts.IsCancellationRequested) return true;
var processes = Process.GetProcesses();
int count = 0;
foreach (var process in processes)
{
if (cts.IsCancellationRequested) { return true; }
if (string.Compare(process.ProcessName, proName, true) == 0)
{
count++;
}
}
if (count == 0)
{
//这里表示指定线程结束了。
OnProcess(new processEventArgs(flag));
flag = false;
}
Thread.Sleep(2);
} while (flag);
return flag;
});
}
}
}链接:https://pan.baidu.com/s/1hARj2-2RCbT0wmFSWwaWuQ
提取码:z9lc
--来自百度网盘超级会员V4的分享
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路



















