C#固定时间执行指定事件(观察者模式+异步委托)
最近有个项目需要每天固定的时间去执行指定的事件,发现网上关于这样的文章比较少,而且比较散。通过学习了几篇文章后终于实现了这个功能,在此也特别感谢这些文章的作者们,这也是我第一次在园子里面发文章,望多指教。
关于观察者模式,我在这里就不做讲解了,如有不懂,可以参考相关文章。
那么开始入正题。
主要有三个页面:Observer.cs(观察者)、Subject.cs(通知者)、Form1.cs
Observer.cs

class Observer
{
/// <summary>
/// 执行事件A
/// </summary>
/// <returns></returns>
public string DoA()
{
return "时间到了,执行事件A~~";
} /// <summary>
///执行事件B
/// </summary>
/// <returns></returns>
public string DoB()
{
return "时间到了,执行事件B~~";
} }

Subject.cs(用于通知观察者的类)

namespace XXXXXX
{
//声明委托
delegate string EventHandler();
class Subject
{
//声明事件
public event EventHandler Output;
public string Notify()
{
string res = "";
if (Output != null)
{
res = Output();
}
return res;
}
}
}

Form1.cs
使用了TextBox控件txtShow和Timer控件timer,timer的时间间隔设为1s

private void timer_Tick(object sender, EventArgs e)
{ Subject subject = new Subject();
Observer observer = new Observer();
string now = DateTime.Now.ToString("HH:mm:ss");
//设置固定时间要执行的事件
switch (now)
{
case "22:28:00":
subject.Output += new EventHandler(observer.DoA);
break;
case "22:29:00":
subject.Output += new EventHandler(observer.DoB);
break;
}
string res = "";
//执行事件
res += subject.Notify();
if (res != "")
{
txtShow.AppendText(now + ":");
txtShow.AppendText(res);
txtShow.AppendText("\r\n");
}
}

结果:

但以上的方法是同步的,也就是第一个方法执行太久的话会影响第二个方法的执行,那么要解决这问题,下面就用到异步委托。
Observer.cs不用修改到,这也是用了观察者模式所带来的好处。
Subject.cs(修改了Notify方法,添加了一个委托、事件和方法)

namespace XXXX
{
//声明委托
delegate string EventHandler();
delegate void ShowInfoHandler(string info);
class Subject
{
//声明事件
public event EventHandler Output;
public event ShowInfoHandler ShowInfoEvent; public void Notify()
{ if (Output != null)
{
foreach(EventHandler handler in Output.GetInvocationList())
{
//异步调用委托,第一个参数为要回调的函数,第二个参数为要向回调函数传入的值
//这里传入被调用方法的委托
handler.BeginInvoke(CallBack, handler); }
} } /// <summary>
/// 回调函数
/// </summary>
/// <param name="show"></param>
public void CallBack(IAsyncResult obj)
{
EventHandler handler = (EventHandler)obj.AsyncState;
//获取被调用方法的返回的信息
string res= handler.EndInvoke(obj);
ShowInfoEvent(res);
} }
}

这里稍微解释一下。ShowInfoHandler、ShowInfoEvent用于向主线程txtShow输出提示信息用的,若不用输出提示信息可以省去。(Form1.cs会用到)
handler.BeginInvoke调用异步委托,第一个参数传入要回调的函数,也就是执行完自身的方法后会继续执行的方法;第二个参数一般传入自身的委托,方便在回调函数中获取执行完返回的信息。
Form1.cs

//非主线程无法操作界面的控件,所以用委托来实现向txtShow输出信息
public void ShowInfo(string info)
{
txtShow.Invoke(new Action(()=>{txtShow.AppendText(info+"\r\n");}));
} private void timer_Tick(object sender, EventArgs e)
{ Subject subject = new Subject();
Observer observer = new Observer();
//将向txtShow输出信息的方法交给subject的委托
subject.ShowInfoEvent += new ShowInfoHandler(ShowInfo);
string now = DateTime.Now.ToString("HH:mm:ss");
switch (now)
{
case "23:20:00":
txtShow.AppendText("现在时间:"+now+"\r\n");
subject.Output += new EventHandler(observer.DoA); break;
case "23:21:00":
txtShow.AppendText("现在时间:"+now+"\r\n");
subject.Output += new EventHandler(observer.DoB);
break;
}
subject.Notify(); }

子线程操作主线程的控件还有其他方法,大家可以尝试下,这里就不整理了。
结果:

http://www.cnblogs.com/chenjiguang/p/4271356.html
C#固定时间执行指定事件(观察者模式+异步委托)的更多相关文章
- java Timer(定时调用、实现固定时间执行)
最近需要用到定时调用的功能.可以通过java的Timer类来进行定时调用,下面是有关Timer的一些相关知识. 其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个 ...
- timer和ScheduledThreadPoolExecutor定时任务和每日固定时间执行
//ScheduledThreadPoolExecutor每三秒执行一次 public static void main(String[] args) { ScheduledThread ...
- Windows 添加计划任务 每隔一定时间执行指定批处理脚本
schtasks /create /sc minute /mo 20 /tn "TestBatch" /tr C:/TestBatch.bat TestBatch.bat echo ...
- C#使用Timer.Interval指定时间间隔与指定时间执行事件
C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件. 指定时间间隔是指按特定的时间间隔,如每1分钟.每10分钟.每1个小时等执行指定事件: 指定时间是指每小时的第30分 ...
- C# 异步委托(AP、APM)
Ø 前言 C# 异步委托也是属于异步编程中的一种,可以称为 Asynchronous Programming(异步编程)或者 Asynchronous Programming Model(异步编程模 ...
- C# 1.0 新特性之异步委托(AP、APM)
Ø 前言 C# 异步委托也是属于异步编程中的一种,可以称为 Asynchronous Programming(异步编程)或者 Asynchronous Programming Model(异步编程模 ...
- sql语句延时执行或者是指定时间执行
--使用waitfor语句延迟或暂停程序的执行 --waitfor{delay'time'|time 'time'} delay是指间隔时间 最长到24小时 time是指定时间执行 waitfor d ...
- Linux 命令 - at: 在指定的时间执行任务
在指定的时间执行任务. 命令格式 at [-V] [-q queue] [-f file] [-mldbv] TIMEat [-V] [-q queue] [-f file] [-mldbv] -t ...
- crontab 在指定时间范围每隔2小时执行一次和指定时间执行实例
crontab 在指定时间范围每隔2小时执行一次和指定时间执行,下面实例实现了:10-23点每两个小时执行一次,2点执行一次,分钟依次是1 2 3 ,没有24点的,晚上12点是0点注:*代表所有的取值 ...
随机推荐
- android activity改变另一个activity ui
android开发之在activity中控制另一个activity的UI更新 转自:http://www.cnblogs.com/ycxyyzw/p/3875544.html 第一种方法: 遇到一 ...
- Why jsp?
Before the JSP come into the world . The CGI and servlet took the responsibility of generating dynam ...
- 绝不在构造和析构函数中调用 virtual 函数
看下面的这段代码,问 print调用的是基类还是派生类的版本? 答案是 基类... 可能大家会很惊讶,print不是virtual function 吗?为什么不是调用派生类的版本呢? 首先,当定义一 ...
- Qt for Android开发Android应用时的各种错误汇总(此片博文不成熟,请大家略过)
“Qt for Android真的很脆弱,项目能跑起来靠的是奇迹,跑不起来,各种报错才是正常...” 问题一:Qt for Android编译不过:make (e=2): 系统找不到指定的文件. 之前 ...
- Html 之div+css布局之css选择器
CSS选择器 什么叫选择器?通俗的来说就是 我想改变html 中某个地方的 字体大小 或者背景色 或者其它属性 内边距 外边距,宽度高度 等等 一些Css 样式. 那么我们如何找到对应的 元素呢? ...
- Android中proc/meminfo的详解(原)
今天在写到获取手机可用内存空间的总大小的时候,通过下面的方法去获取的时候,发现该方法最低支持的版本是16,这显然是不可取的. public static long getTotalSpace(Cont ...
- ORA-20000 ORU-10027 buffer overflow limit of 2000 bytes
这是在pl/sql中执行存储过程报的错,原因是serveroutput限制存储, 解决方案:set serveroutput on size 10000000;
- Runtime Complexity of .NET Generic Collection
Runtime Complexity of .NET Generic Collection I had to implement some data structures for my compu ...
- C语言指针,你还觉得难吗?
在研究式学习-c语言程序设计指针式这样介绍的: 内存中存储变量的第一个单元的地址 称为指针,存放指针的变量称为指针变量: 变量的访问方式有: 直接访问方式:按变量名查找其首地址 间接访问方式:通过指针 ...
- overflow:hidden清楚浮动的影响
在网页布局中有时会遇到这种情况: 如果左边用<dt>,右边用<dd>,放在一行显示,<dt>要设置float:left,这个应该都知道,问题是,第一行这样做没有问题 ...