最近有个项目需要每天固定的时间去执行指定的事件,发现网上关于这样的文章比较少,而且比较散。通过学习了几篇文章后终于实现了这个功能,在此也特别感谢这些文章的作者们,这也是我第一次在园子里面发文章,望多指教。

关于观察者模式,我在这里就不做讲解了,如有不懂,可以参考相关文章。

那么开始入正题。

主要有三个页面: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#固定时间执行指定事件(观察者模式+异步委托)的更多相关文章

  1. java Timer(定时调用、实现固定时间执行)

    最近需要用到定时调用的功能.可以通过java的Timer类来进行定时调用,下面是有关Timer的一些相关知识. 其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个 ...

  2. timer和ScheduledThreadPoolExecutor定时任务和每日固定时间执行

    //ScheduledThreadPoolExecutor每三秒执行一次 public static void main(String[] args) {        ScheduledThread ...

  3. Windows 添加计划任务 每隔一定时间执行指定批处理脚本

    schtasks /create /sc minute /mo 20 /tn "TestBatch" /tr C:/TestBatch.bat TestBatch.bat echo ...

  4. C#使用Timer.Interval指定时间间隔与指定时间执行事件

    C#中,Timer是一个定时器,它可以按照指定的时间间隔或者指定的时间执行一个事件. 指定时间间隔是指按特定的时间间隔,如每1分钟.每10分钟.每1个小时等执行指定事件: 指定时间是指每小时的第30分 ...

  5. C# 异步委托(AP、APM)

    Ø  前言 C# 异步委托也是属于异步编程中的一种,可以称为 Asynchronous Programming(异步编程)或者 Asynchronous Programming Model(异步编程模 ...

  6. C# 1.0 新特性之异步委托(AP、APM)

    Ø  前言 C# 异步委托也是属于异步编程中的一种,可以称为 Asynchronous Programming(异步编程)或者 Asynchronous Programming Model(异步编程模 ...

  7. sql语句延时执行或者是指定时间执行

    --使用waitfor语句延迟或暂停程序的执行 --waitfor{delay'time'|time 'time'} delay是指间隔时间 最长到24小时 time是指定时间执行 waitfor d ...

  8. Linux 命令 - at: 在指定的时间执行任务

    在指定的时间执行任务. 命令格式 at [-V] [-q queue] [-f file] [-mldbv] TIMEat [-V] [-q queue] [-f file] [-mldbv] -t ...

  9. crontab 在指定时间范围每隔2小时执行一次和指定时间执行实例

    crontab 在指定时间范围每隔2小时执行一次和指定时间执行,下面实例实现了:10-23点每两个小时执行一次,2点执行一次,分钟依次是1 2 3 ,没有24点的,晚上12点是0点注:*代表所有的取值 ...

随机推荐

  1. android activity改变另一个activity ui

    android开发之在activity中控制另一个activity的UI更新   转自:http://www.cnblogs.com/ycxyyzw/p/3875544.html 第一种方法: 遇到一 ...

  2. Why jsp?

    Before the JSP come into the world . The CGI and servlet took the responsibility of generating dynam ...

  3. 绝不在构造和析构函数中调用 virtual 函数

    看下面的这段代码,问 print调用的是基类还是派生类的版本? 答案是 基类... 可能大家会很惊讶,print不是virtual function 吗?为什么不是调用派生类的版本呢? 首先,当定义一 ...

  4. Qt for Android开发Android应用时的各种错误汇总(此片博文不成熟,请大家略过)

    “Qt for Android真的很脆弱,项目能跑起来靠的是奇迹,跑不起来,各种报错才是正常...” 问题一:Qt for Android编译不过:make (e=2): 系统找不到指定的文件. 之前 ...

  5. Html 之div+css布局之css选择器

    CSS选择器 什么叫选择器?通俗的来说就是 我想改变html 中某个地方的  字体大小 或者背景色 或者其它属性 内边距 外边距,宽度高度 等等 一些Css 样式. 那么我们如何找到对应的 元素呢? ...

  6. Android中proc/meminfo的详解(原)

    今天在写到获取手机可用内存空间的总大小的时候,通过下面的方法去获取的时候,发现该方法最低支持的版本是16,这显然是不可取的. public static long getTotalSpace(Cont ...

  7. ORA-20000 ORU-10027 buffer overflow limit of 2000 bytes

    这是在pl/sql中执行存储过程报的错,原因是serveroutput限制存储, 解决方案:set serveroutput on size 10000000;

  8. Runtime Complexity of .NET Generic Collection

    Runtime Complexity of .NET Generic Collection   I had to implement some data structures for my compu ...

  9. C语言指针,你还觉得难吗?

    在研究式学习-c语言程序设计指针式这样介绍的: 内存中存储变量的第一个单元的地址 称为指针,存放指针的变量称为指针变量: 变量的访问方式有: 直接访问方式:按变量名查找其首地址 间接访问方式:通过指针 ...

  10. overflow:hidden清楚浮动的影响

    在网页布局中有时会遇到这种情况: 如果左边用<dt>,右边用<dd>,放在一行显示,<dt>要设置float:left,这个应该都知道,问题是,第一行这样做没有问题 ...