zoukankan      html  css  js  c++  java
  • 用并发队列(ConcurrentQueue)实现多线程任务中随时异步回调进度通知(.Net4.0)

    本文讲述实现抽象出来的异步通知回调进度通知,用在多层组件中,支持一组task的任意进度回调通知。本文中用到几个.NET 4.0的新方法和TPL方法:TupleConcurrentQueueSemaphoreSlimTask...说明:如果你是一个简单的Task可能无需这么复杂,用传入Action同步回调即可,但是注意NotifyProgress也就是在任务执行过程中随时同步通知进度,会造成你任务阻塞。如果你是在UI层,用BackgroundWorkder最简单了。(本文原创http://mainz.cnblogs.com,转载请注明。)

       //异步操作,代替Thread, threadPool
       Task _ProgressQueueTask = null;
       //限制并发访问资源的线程数,SemaphoreSlim开销低于Semaphore50倍
       SemaphoreSlim _ProgressCounter = null;
       //并发队列ConcurrentQueue,线程安全的队列
       //Tuple:元数据结构,可以方便的访问其item
       ConcurrentQueue<tuple<progressaction, string,="" int?="">> _ProgressQueue = new ConcurrentQueue<tuple<progressaction, string,="" int?="">>();
       Action<progressaction, string,="" int?=""> _OnProgress;
         public Action<progressaction, string,="" int?=""> OnProgress
         {
             get {  return _OnProgress; }
             set
            {
               _OnProgress = value;
               if (_ProgressQueueTask == null)
               {
                       _ProgressQueueTask = new Task(() =>
                       {
                              while (true)
                               {
                                   Tuple<progressaction, string,="" int?=""> item;
                                   //查询队列
                                   if (_ProgressQueue.TryDequeue(out item))
                                   {
                                       OnProgress(item.Item1, item.Item2, item.Item3);
                                   }
                                   else
                                   {
                                       //线程等待信号,由NotifyProgress入队列并给予信号
                                       _ProgressCounter.Wait();
                                   }
                               }
                           },
                           TaskCreationOptions.LongRunning);
                    _ProgressCounter = new SemaphoreSlim(0, 10);//初始0,最大限制10
                       _ProgressQueueTask.Start();
                   }
               }
           }
           //在任何Task的执行过程中,或一组task的执行过程中,可以调用此方法来异步回调随时通知进度,而不会阻塞本任务
           public void NotifyProgress(ProgressAction action, string item = null, long? current = null, long? maxCount = null)
           {
               if (OnProgress != null)
               {
                   int? percent = null;
                   if (current.HasValue && maxCount.HasValue)
                   {
                       percent = (int)((double)current.Value / (double)maxCount.Value * 100.0);
                   }
                   _ProgressQueue.Enqueue(Tuple.Create(action, item, percent));
                   _ProgressCounter.Release();
               }
               return;
           }
          public enum ProgressAction
          {
                   Adding,
                   Extracting,
                   Extracted,
                   Validating,
                   Validated,
                   Deleting,
                   Deleted,
                   Restore
          };
           //用法:
           //中间层
           NotifyProgress(ProgressAction.Extracting, "abc");
           //界面层
           OnProgress = (action, file, percent) =>
                       {  
                              //...
                        }
    

    10.13

    有问题请回复。本文结束,代码带注释。

  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/Mainz/p/2209924.html
Copyright © 2011-2022 走看看