C# 中 SetTimeout 方案
近期项目中需在用户点击按钮后,延时执行代码逻辑,避免频繁操作。网上没找到有关 C# SetTimeout 官方API , 于是通过异步线程,动手实现一个。方案如下,如果同一个DelayedProcess 对象连续调用 SetTimeout 多次 ,默认取消前一次调用。
public class DelayedProcess<Req,Rsp>
{
public delegate void ExcuteMethod(Result rsp);
CancellationTokenSource tokenSource;
public class Result {
public Req request {
get;
set;
}
public Rsp response {
get;
set;
}
/// <summary>
/// 抛出异常信息
/// </summary>
public Exception ex;
/// <summary>
/// 是否延时执行成功
/// </summary>
public bool IsSuccess {
get;
set;
}
}
async void TaskDelay(int timeout, CancellationToken token, ExcuteMethod method, Result rsp)
{
try
{
await Task.Delay(timeout, token);
rsp.IsSuccess = true;
rsp.ex = null;
}
catch (Exception ex)
{
rsp.ex = ex;
rsp.IsSuccess = false;
}
finally {
method(rsp);
}
}
public void SetTimeout(int timeout, ExcuteMethod method, Result rsp)
{
Cancel();
tokenSource = new CancellationTokenSource();
TaskDelay(timeout, tokenSource.Token, method , rsp);
}
public void Cancel()
{
if (tokenSource != null && !tokenSource.IsCancellationRequested)
{
tokenSource.Cancel();
}
}
}
调用示例:
DelayedProcess<string, string> dp = new DelayedProcess<string, string>(); private void button1_Click(object sender, EventArgs e) { Console.WriteLine("{0}:{1}", DateTime.Now, "开始请求"); dp.SetTimeout(2000, (arg) => { if (arg.IsSuccess) { Console.WriteLine("{0}:延时执行{1}", DateTime.Now, arg.request); } else { Console.WriteLine("{0}:延时失败,{1}", DateTime.Now, arg.ex.Message); } }, new DelayedProcess<string, string>.Result() { request = "1111" }); }
浙公网安备 33010602011771号