最近做项目遇到一个问题,需要调用某个API实现与下位机通讯,但下位机可能会存在掉线的情况,为保证程序不会卡死,需要给调用程序设定一个超时时间,超时后需要提醒主程序错误。
参照了CSDN上一些范例代码,主要实现方法是采用委托、通过委托的BeginInvoke调用程序并传入CallBack函数,通过ManualResetEvent().WaitOne()设定超时时间,通过EndInvoke()实现调用结果查看,范例代码如下:
//异步超时类
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TimeoutTest
{
public class ReadDataHandler
{
public delegate void delEvent();
private ManualResetEvent mEvent = new ManualResetEvent(true);
public void Task()
{
Thread.Sleep(2000);
Console.WriteLine("**************Doing something*****************");
}
public delEvent taskTodo;
private bool timeoutFlag = false;
public bool TestTimeOut(int durationMs)
{
if(this.taskTodo == null)
{
return false;
}
this.mEvent.Reset();
this.timeoutFlag = true;
this.taskTodo.BeginInvoke(DoAsyncCallBack, null);
if(!this.mEvent.WaitOne(durationMs, false))
{
this.timeoutFlag = true;
}
return this.timeoutFlag;
}
public void DoAsyncCallBack(IAsyncResult result)
{
try
{
this.taskTodo.EndInvoke(result);
this.timeoutFlag = false;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
this.timeoutFlag = true;
}
finally
{
this.mEvent.Set();
}
}
}
}
以下是测试类:
//测试类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeoutTest
{
class Program
{
static void Main(string[] args)
{
ReadDataHandler handler = new ReadDataHandler();
handler.taskTodo = handler.Task;
bool result = handler.TestTimeOut(10000);
Console.WriteLine("是否超时? " + result);
Console.ReadKey();
}
}
}