码迷,mamicode.com
首页 > 其他好文 > 详细

一种延迟方法调用的实现

时间:2014-10-11 17:13:25      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   strong   

需求场景

最近遇到一种场景,需要延迟某个步骤的实现,以便在延迟的过程中能够及早处理,从而取消任务。 比如,现在的服务器CPU过高了,则系统记录下来,然后开始发送邮件通知用户,但是如果在10秒之内CPU恢复了;或者我不希望用户得知这个CPU的信息,因为我就在现场,我可以及时知道怎么处理这种情况,这个时候准备拨打电话的这个方法的调用就不能被执行,需要延迟一段时间,以便能够被取消——以上场景仅供参考。

代码实现

  以下是我的一个实现方式,供大家讨论,或者有更好的方式可以改进。

这种方法旨在能够方便的延迟任意方法的执行:

定义任务接口 

  这是一个基本的线程任务的接口,包括任务名称、线程的运行状态、启停线程。

1     interface ITask
2     {
3         string Name { get; }
4         bool IsRunning { get; }
5         void Start();
6         void Stop();
7         void Run();

8     } 

  定义延迟的信息类

  保存当前需要延迟的方法,以及需要延迟的时间等

  1         class LazyItem

 2         {
 3             private readonly int _timeout;
 4             private readonly DateTime _enqueueTime;
 5 
 6             public bool IsTimeout
 7             {
 8                 get { return (DateTime.Now - _enqueueTime).TotalSeconds > _timeout; }
 9             }
10             public string Key { getprivate set; }
11             public Action Continue { getprivate set; }
12 
13             public LazyItem(string key, int timeout, Action continueAction)
14             {
15                 _enqueueTime = DateTime.Now;
16                 _timeout = timeout;
17                 Key = key;
18                 Continue = continueAction;
19             }
20         }

  延迟的实现

  主要是执行一个定时的任务,去检测被延迟的方法是否达到了超时的时间,如果达到,则执行该方法。另外,提供一个可供取消方法的函数。

     class LazyInvoker : ITask

    {
        public string Name
        {
            get { return "Lazy Invoke Task"; }
        }

        public bool IsRunning { getprivate set; }

        private readonly ConcurrentDictionary<string, LazyItem> _lazyActions = new ConcurrentDictionary<string, LazyItem>();

        public void Start()
        {
            Task.Factory.StartNew(Run);
            IsRunning = true;
        }

        public void Stop()
        {
            IsRunning = false;
        }

        /// <summary>
        
/// 检测被延迟的任务,达到超时时间则触发
        
/// </summary>
        
/// Created by:marvin(2014/10/11 12:14)
        public void Run()
        {
            while (IsRunning)
            {
                if (_lazyActions.Count > 0)
                {
                    var removeKeys = (from lazyItem in _lazyActions where lazyItem.Value.IsTimeout select lazyItem.Key).ToList();
                    if (removeKeys.Count > 0)
                    {
                        foreach (var key in removeKeys)
                        {
                            LazyItem tmp;
                            if (_lazyActions.TryRemove(key, out tmp))
                            {
                                tmp.Continue();
                            }
                        }
                    }
                }

                Thread.Sleep(1 * 1000);
            }
        }

        /// <summary>
        
/// 延迟工作
        
/// </summary>
        
/// <param name="id">The identifier.</param>
        
/// <param name="lazyTimeout">The lazy timeout.</param>
        
/// <param name="continueAction">The continue action.</param>
        
/// Created by:marvin(2014/10/11 11:48)
        public void LazyDo(string id, int lazyTimeout, Action continueAction)
        {
            if (!_lazyActions.ContainsKey(id))
            {
                if (_lazyActions.TryAdd(id, new LazyItem(id, lazyTimeout, continueAction)))
                {
                    Console.WriteLine("lazy action : {0} , timeout : {1}", id, lazyTimeout);
                }
            }
        }

        /// <summary>
        
/// 取消任务
        
/// </summary>
        
/// <param name="actionKey">The action key.</param>
        
/// Created by:marvin(2014/10/11 12:02)
        public void Cancel(string actionKey)
        {
            if (_lazyActions.ContainsKey(actionKey))
            {
                LazyItem tmp;
                if (_lazyActions.TryRemove(actionKey, out tmp))
                {
                    Console.WriteLine("lazy action “{0}” had removed", tmp.Key);
                }
            }
        }
    }

 测试

  1     class Program

 2     {
 3         static void Main(string[] args)
 4         {
 5             var lazyInvoker = new LazyInvoker();
 6             lazyInvoker.Start();
 7 
 8             //延迟7秒运行
 9             lazyInvoker.LazyDo(Guid.NewGuid().ToString(), 7, DoSomething);
10             Thread.Sleep(5 * 1000);
11 
12             //延迟3秒运行,但是3秒的时候被取消
13             var id = Guid.NewGuid().ToString();
14             lazyInvoker.LazyDo(id, 5, DoSomething);
15             Thread.Sleep(3 * 1000);
16             lazyInvoker.Cancel(id);
17 
18             Console.ReadKey();
19         }
20 
21         private static void DoSomething()
22         {
23             Console.WriteLine("Now time is :" + DateTime.Now.ToString("HH:mm:ss"));
24         }
25     }

  运行结果如下:

 bubuko.com,布布扣

 

一种延迟方法调用的实现

标签:style   blog   http   color   io   os   ar   for   strong   

原文地址:http://www.cnblogs.com/marvin/p/lazyInvokeMethod.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!