日期:2014-05-20  浏览次数:21004 次

C#.NET Timer时钟与异步的问题
C#.Net程序。
private void timer_Tick(object sender, System.EventArgs e)
{
  if (DateTime.Now.Second % 5 == 0)
  {
  Method1();
  Method2();
  }
 }
Method1()每五秒从数据库读取数据更新
Method2() 这个也从数据库读出 ,不过是从别的数据库转移过来的数据,转移过程中可能出差,这时候Method2()要判断数据请求时间是否超过60秒,如果超过60秒,做别的处理。

问题出来了:每5秒中更新一次,Method1()数据读出出来每问题,可是Method2()的读取速度慢,可能上60秒还没有出来,
这时候winform可能页面一片空白或不能编辑界面。

这时候我用异步操作
  delegate double LoadDataHandler();
  public partial class frmAsync : Form
  {
  public frmAsync()
  {
  InitializeComponent();
  }

  private void timer1_Tick(object sender, EventArgs e)
  {
  int second = DateTime.Now.Second;
  Method1(second);

  if (second % 10 == 0)
  {
  Method2();
  }
  }

  private void Method1(int s)
  {
  label1.Text = s.ToString();
  }

  private void Method2()
  {
  LoadDataHandler handler = new LoadDataHandler(this.LoadData);
  IAsyncResult result = handler.BeginInvoke(new AsyncCallback(this.CompleteCallBack), null);
  }

  private double LoadData()
  {
  TimeSpan start = new TimeSpan(DateTime.Now.Ticks);
  //模拟迟缓读出,20秒
  System.Threading.Thread.Sleep(20000);
  TimeSpan end = new TimeSpan(DateTime.Now.Ticks);
  TimeSpan span = end.Subtract(start).Duration();
  return span.TotalSeconds;
  }  

  /// <summary>  
  /// 当调用LoadData结束时执行这个方法  
  /// </summary>  
  /// <param name="result"></param>  
  private void CompleteCallBack(IAsyncResult r)
  {
  AsyncResult result = (AsyncResult)r;
  LoadDataHandler handlerSource = (LoadDataHandler)result.AsyncDelegate;
  double t;
  //执行结束,获取执行结果的数据
  if (result.IsCompleted)
  {
  t = handlerSource.EndInvoke(r);
  MessageBox.Show(t.ToString());
  }
  }
  }

在上面的方法LoadData()
第一次执行这个方法会sleep20秒(CompleteCallBack弹出的消息显示20),
可是第二次或者以后走这个方法的时候,每次都sleep 10秒(也就是说,跟着timer1_Tick方法走了,在LoadData没有停留了),虽然CompleteCallBack回显示20,但是从时间上看,只有10秒的sleep,百思不知其解,再麻烦大家提示下。

------解决方案--------------------
C# code

static int inTimer=0;//定义一个全局变量
System.Threading.Timer T = new System.Threading.Timer(new TimerCallback(CallbackFunc), null, 0,10000);//new 一个System.Threading.Timer类的实例,详细请参考System.Threading.Timer这个类的资料
void CllbackFunc(object obj) //回调函数,当时间到达时执行
{
   //检查整个函数有没有执行完毕,若没有就跳过本次,等待下次时间的到来
   if (Interlocked.Exchange(ref inTimer, 1) == 0) 
   {
      //ToDo: ****************
   }
   Interlocked.Exchange(ref inTimer, 0);
}