Await multiple async Task while setting max running task at a time

后端 未结 4 981
失恋的感觉
失恋的感觉 2020-12-19 12:19

So I just started to try and understand async, Task, lambda and so on, and I am unable to get it to work like I want. With the code below I want for it to lock btnDoWebReque

4条回答
  •  庸人自扰
    2020-12-19 12:51

    There are a couple of things wrong with your code:

    1. Using Wait() on a Task is like running things synchronously, hence you only notice the UI reacting when everything is done and the button reenabled. You need to await an async method in order for it to truely run async. More so, if a method is doing IO bound work like a web request, spinning up a new Thread Pool thread (using Task.Factory.StartNew) is redundant and is a waste of resources.

    2. Your button click event handler needs to be marked with async so you can await inside your method.

    3. I've cleaned up your code a bit for clarity, using the new SemaphoreSlim WaitAsync and replaced your for with a LINQ query. You may only take the first two points and apply them to your code.

      private SemaphoreSlim maxThread = new  SemaphoreSlim(3);
      
      private async void btnDoWebRequest_Click(object  sender, EventArgs e)
      {
          btnDoWebRequest.Enabled = false;
          await DoWebRequest();
          btnDoWebRequest.Enabled = true;
       }
      
       private async Task DoWebRequest()
       {
           List requestInfoList = new List();
      
           var requestInfoList =  dataRequestInfo.Rows.Select(x => x.Tag).Cast();
      
          var tasks = requestInfoList.Select(async I => 
          {
               await maxThread.WaitAsync();
               try
               {
                   await Global.webRequestWork(i);
               }
               finally
               {
                   maxThread.Release();
               }
         });
      
         await Task.WhenAll(tasks);
      

提交回复
热议问题