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);
}