限制任务并行库的线程数我有几百个文件需要上传到AzureBlobStorage。我想使用并行任务库。但是我如何在foreach文件列表中运行所有100个线程上传,如何限制它可以使用的最大线程数并并行执行作业。还是自动平衡的东西?你根本不应该使用线程。有一个基于任务的API,它自然是异步的:CloudBlockBlob.UploadFromFileAsync。将它与async/await和SemaphoreSlim一起使用来限制并行上传的数量。示例(未经测试):constMAX_PARALLEL_UPLOADS=5;asyncTaskUploadFiles(){varfiles=newList();//...添加文件到列表//初始化blob块和//使用异步上传文件(varblobBlock=newCloudBlockBlob(url,credentials))文件。Select(async(filename)=>{awaitsemaphore.WaitAsync();try{awaitblobBlock.UploadFromFileAsync(filename,FileMode.Create);}finally{semaphore.Release();}}).ToArray();等待Task.WhenAll(任务);你试过使用MaxDegreeOfParallelism吗?像这样:System.Threading.Tasks.Parallel.Invoke(newTasks.ParallelOptions{MaxDegreeOfParallelism=5},actionsArray)基本上你会想为每个你想上传的文件创建一个动作或任务,把它们放在一个列表中,那然后处理列表,限制可以并行处理的数量。我的博客文章展示了如何使用Tasks和Actions执行此操作,并提供了一个示例项目,您可以下载并运行以查看两者的实际效果。使用Actions如果使用Actions,则可以使用内置的.NetParallel.Invoke函数。这里我们限制它最多并行运行5个线程。varlistOfActions=newList();foreach(文件中的var文件){varlocalFile=file;//请注意,我们在这里创建了任务,但没有启动它。listOfTasks.Add(newTask(()=>blobBlock.UploadFromFileAsync(localFile,FileMode.Create)));}varoptions=newParallelOptions{MaxDegreeOfParallelism=5};Parallel.Invoke(选项,listOfActions.ToArray());但是,此选项不使用UploadFromFileAsync的异步性质,因此您可能希望使用下面的任务示例。对于任务,使用任务时没有内置功能。但是,您可以使用我在我的博客上提供的那个。//////启动给定的任务并等待它们完成。这将最多并行运行指定数量的任务。///注意:如果给定任务之一已经启动,将抛出异常。//////要运行的任务。///并行运行的最大任务数。///取消令牌。publicstaticasyncTaskStartAndWaitAllThrottledAsync(IEnumerabletasksToRun,intmaxTasksToRunInParallel,CancellationTokencancellationToken=newCancellationToken()){awaitStartAndWaitAllThrottledAsync(tasksToRun,maxTasksToRunInParallel,-1,cancellationToken);}//////启动给定的任务并等待它们完成。这将并行运行指定数量的任务。///注意:如果在任务完成之前达到超时,则可能会启动另一个任务,可能运行超过指定的最大允许。///注意:如果给定的任务之一已经开始,则会出现异常投掷。//////要运行的任务。///并行运行的最大任务数。///在允许另一个任务开始之前,我们应该允许最大任务并行运行的最大毫秒数。指定-1无限期等待。///取消令牌。publicstaticasyncTaskStartAndWaitAllThrottledAsync(IEnumerabletasksToRun,intmaxTasksToRunInParallel,inttimeoutInMilliseconds,CancellationTokencancellationToken=newCancellationToken()){//转换为任务列表,这样我们就不会不必要地多次枚举它。vartasks=tasksToRun.ToList();使用(varthrottler=newSemaphoreSlim(maxTasksToRunInParallel)){varpostTaskTasks=newList();//让每个任务在完成时通知节流器,以便它减少当前运行的任务数。tasks.ForEach(t=>postTaskTasks.Add(t.ContinueWith(tsk=>throttler.Release())));//开始运行每个任务。foreach(vartaskintasks){//自增t当前正在运行的任务数,如果正在运行太多则等待。等待throttler.WaitAsync(timeoutInMilliseconds,cancellationToken);cancellationToken.ThrowIfCancellationRequested();任务.开始();}//等待所有提供的任务完成。//我们等待“post”任务列表而不是原始任务,否则存在潜在的竞争条件,即在某些任务完成其“post”操作之前退出节流器的使用块,这引用了节流器,结果由于访问已处置的对象而发生异常。awaitTask.WhenAll(postTaskTasks.ToArray());然后创建任务列表并调用函数让它运行,一次最多同时执行5个,你可以这样做:varlistOfTasks=newList();foreach(文件中的var文件){varlocalFile=file;//请注意,我们在这里创建了任务,但没有启动它。listOfTasks.Add(newTask(async()=>awaitblobBlock.UploadFromFileAsync(localFile,FileMode.Create)));}awaitTasks.StartAndWaitAllThrottledAsync(listOfTask小号,5);您可以通过运行以下命令找到答案:classProgram{staticvoidMain(string[]args){varlist=newList();for(inti=0;iAction(refrunningIndex));Parallel.ForEach(list,i=>{runningIndex++;Console.WriteLine(i);Thread.Sleep(3000);});控制台.ReadKey();}privatestaticvoidAction(refintnumber){while(true){Console.WriteLine("通过{0}",number);线程.睡眠(2900);}}}如您所见,并行度开始时很小,然后变大,最后变小,因此必须进行某种自动优化。以上就是《C#学习教程:限制任务并行库线程数》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:
