框架中有什么东西可以让我异步执行委托队列吗?我的意思是我希望代表们按照他们排队的顺序一次执行一个,但我希望整个过程异步运行。队列也不是固定的,其他代表会定期添加,一旦到达队列顶部就应该处理。我不需要专门使用Queue,这就是我描述所需行为的方式。我可以自己写一些东西来做,但如果有内置的东西我可以使用,而不是更好。我简要地查看了ThreadPool.QueueUserWorkItem,因为它允许顺序执行,但可以找到一种令人满意的方法来防止一次执行多个。框架中是否有允许我异步执行委托队列的东西?我将其实现为自定义任务调度程序。然后,您可以将委托作为任务排队并运行,这将为您提供异常处理、取消以及异步/等待的所有好处。使用BlockingCollection实现按顺序执行代理的任务计划程序非常简单。下面的SerialTask??Scheduler是StephenToub的StaTaskScheduler的简化版:usingSystem;使用System.Collections.Concurrent;使用System.Collections.Generic;使用System.Linq;使用系统线程;使用System.Threading.Tasks;namespaceConsole_21628490{//测试类程序{staticasyncTaskDoWorkAsync(){using(varscheduler=newSerialTask??Scheduler()){vartasks=Enumerable.Range(1,10).Select(i=>scheduler.Run(()=>{varsleep=1000/i;Thread.Sleep(sleep);Console.WriteLine("Task#"+i+",sleep:"+sleep);},CancellationToken.None));等待Task.WhenAll(任务);}}staticvoidMain(string[]args){DoWorkAsync().Wait();控制台.ReadLine();}}//SerialTask??Scheduler公共密封类SerialTask??Scheduler:TaskScheduler,IDisposable{Task_schedulerTask;阻塞集合_tasks;线程_schedulerThread;publicSerialTask??Scheduler(){_tasks=newBlockingCollection();_schedulerTask=Task.Run(()=>{_schedulerThread=Thread.C当前线程;foreach(vartaskin_tasks.GetConsumingEnumerable())TryExecuteTask(task);});}protectedoverridevoidQueueTask(Tasktask){_tasks.Add(task);}protectedoverrideIEnumerableGetScheduledTasks(){return_tasks.ToArray();}protectedoverrideboolTryExecuteTaskInline(Tasktask,booltaskWasPreviouslyQueued){return_schedulerThread==Thread.CurrentThread&&TryExecuteTask(任务);}publicoverrideintMaximumConcurrencyLevel{get{return1;}}publicvoidDispose(){if(_schedulerTask!=null){_tasks.CompleteAdding();_schedulerTask.Wait();_tasks.Dispose();_任务=空;_schedulerTask=null;}}publicTaskRun(Actionaction,CancellationTokentoken){returnTask.Factory.StartNew(action,token,TaskCreationOptions.None,this);}publicTaskRun(Funcaction,CancellationTokentoken){returnTask.Factory.StartNew(action,token,TaskCreationOptions.None,this).Unwrap();}publicTaskRun(Func>action,CancellationTokentoken){returnTask.Factory.StartNew(action,token,TaskCreationOptions.None,this).Unwrap();输出:任务#1,睡眠:1000任务#2,睡眠:500任务#3,睡眠:333任务#4,睡眠:250任务#5,睡眠:200任务#6,睡眠:166任务#7,sleep:142task#8,sleep:125task#9,sleep:111task#10,sleep:100您可以使用TPL数据流的ActionBlock,只需入队一个包含Delegate和参数列表的ActionBlock类,一次只会执行一个ActionBlock时间。varblock=newActionBlock(_=>_.Action.DynamicInvoke(_.Paramters));classItem{publicDelegateAction{get;私有集;}publicobject[]参数{get;私有集;}publicItem(Delegateaction,object[]parameters){Action=action;参数=参数;一个更简单的选择是使用Action的ActionBlock,但这会强制你捕获参数:如果它对你有用并且你需要了解更多C#学习教程,我希望你多关注它——varblock=newActionBlock(action=>action());block.Post(()=>Console.WriteLine(message));本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
