限制运行的并发任务总数

时间:2017-05-12 14:31:47

标签: c# multithreading azure concurrency azure-web-sites

我有一个方法Create,只要在服务总线消息队列(https://azure.microsoft.com/en-us/services/service-bus/)上看到新消息就会执行该方法。
我试图限制所有Create到5个任务的调用可并行运行的并发任务总数。
在我的代码中,Parallel.ForEach似乎没有做任何事情。

我试图在makePdfAsync()调用周围添加一个互斥/锁定,如下所示:

mutex.WaitOne();
if(curretNumTasks < MaxTasks)
{
    tasks.Add(makePdfAsync(form));
}
mutex.ReleaseMutex();

但它非常慢并且使服务总线投入。

如何限制Create所有调用创建的并发任务数?

public async Task Create(List<FormModel> forms)
 {
     var tasks = new List<Task>();

     Parallel.ForEach(forms, new ParallelOptions { MaxDegreeOfParallelism = 5 }, form =>
     {
         tasks.Add(makePdfAsync(form));
     });
     await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(TimeSpan.FromMinutes(10)));
 }

 public async Task makePdfAsync()
 {
     var message = new PdfMessageModel();
     message.forms = new List<FormModel>() { form };

     var retry = 10;
     var uri = new Uri("http://localhost.:8007");
     var json = JsonConvert.SerializeObject(message);

     using (var wc = new WebClient())
     {
         wc.Encoding = System.Text.Encoding.UTF8;

         // reconnect with delay in case process is not ready
         while (true)
         {
             try
             {
                 await wc.UploadStringTaskAsync(uri, json);
                 break;
             }
             catch
             {
                 if (retry-- == 0) throw;
             }
         }
     }
 }

TL; DR。 Create是类的一个方法,它同时在许多实例上调用。并发性是两倍;同时和Create几个任务的几次调用同时进行Create的几次调用 如何限制在任何一点运行的任务总数?

1 个答案:

答案 0 :(得分:0)

您可以查看使用系统范围的信号量吗?

例如:

var throttle = new Semaphore(5,5,"pdftaskthrottle");

if (throttle.WaitOne(5000)){
    try{
       //do some task / thread stuff
       .....
    } catch(Exception ex){
       // handle
    } finally {
      //always remember to release the semaphore
      throttle.Release();
    }
} else {
   //we timed out ... try again?
}