c# – 为什么运行一百个异步任务需要比运行一百个线程更长的时间
发布时间:2020-12-15 06:49:47 所属栏目:百科 来源:网络整理
导读:为什么运行一百个异步任务需要比运行一百个线程更长的时间? 我有以下测试类: public class AsyncTests{ public void TestMethod1() { var tasks = new ListTask(); for (var i = 0; i 100; i++) { var task = new Task(Action); tasks.Add(task); task.Sta
为什么运行一百个异步任务需要比运行一百个线程更长的时间?
我有以下测试类: public class AsyncTests { public void TestMethod1() { var tasks = new List<Task>(); for (var i = 0; i < 100; i++) { var task = new Task(Action); tasks.Add(task); task.Start(); } Task.WaitAll(tasks.ToArray()); } public void TestMethod2() { var threads = new List<Thread>(); for (var i = 0; i < 100; i++) { var thread = new Thread(Action); threads.Add(thread); thread.Start(); } foreach (var thread in threads) { thread.Join(); } } private void Action() { var task1 = LongRunningOperationAsync(); var task2 = LongRunningOperationAsync(); var task3 = LongRunningOperationAsync(); var task4 = LongRunningOperationAsync(); var task5 = LongRunningOperationAsync(); Task[] tasks = {task1,task2,task3,task4,task5}; Task.WaitAll(tasks); } public async Task<int> LongRunningOperationAsync() { var sw = Stopwatch.StartNew(); await Task.Delay(500); Debug.WriteLine("Completed at {0},took {1}ms",DateTime.Now,sw.Elapsed.TotalMilliseconds); return 1; } } 尽可能地告诉我们,TestMethod1和TestMethod2应该完全一样.一个使用TPL,两个使用普通的香草线程.一个需要1:30分钟,两次需要0.54秒. 为什么? 解决方法
Action方法正在使用Task.WaitAll(任务)阻止.当使用任务默认情况下,ThreadPool将被用于执行,这意味着您正在阻止共享的ThreadPool线程.
尝试以下内容,您将看到相同的效果: 添加一个非阻塞的Action实现,我们称之为ActionAsync private Task ActionAsync() { var task1 = LongRunningOperationAsync(); var task2 = LongRunningOperationAsync(); var task3 = LongRunningOperationAsync(); var task4 = LongRunningOperationAsync(); var task5 = LongRunningOperationAsync(); Task[] tasks = {task1,task5}; return Task.WhenAll(tasks); } >修改TestMethod1以正确处理新的任务返回的ActionAsync方法 public void TestMethod1() { var tasks = new List<Task>(); for (var i = 0; i < 100; i++) { tasks.Add(Task.Run(new Func<Task>(ActionAsync))); } Task.WaitAll(tasks.ToArray()); } 你的性能很慢的原因是因为ThreadPool会“慢慢地”产生新的线程,如果你要阻止它可用的几个线程,你会遇到明显的减速.这就是为什么ThreadPool仅用于运行短任务的原因. 如果您打算使用Task运行长时间阻塞操作,那么在创建Task实例时,请确保使用TaskCreationOptions.LongRunning(这将创建一个新的底层Thread而不是使用ThreadPool). ThreadPool的一些进一步证据是问题,以下也可以减轻你的问题(不要使用这个): ThreadPool.SetMinThreads(500,500); 这表明新的ThreadPool线程的“慢”产生导致您的瓶颈. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |