【问题标题】:is it necessary to wait for termination of all the threads before request gets complete in MVC是否有必要在 MVC 中的请求完成之前等待所有线程的终止
【发布时间】:2017-02-01 22:20:27
【问题描述】:

我正在开发一个 web api 项目,用户在该项目中执行一些操作,所有相关用户都会收到有关用户活动的通知。为了通知每个用户,我正在启动一个执行期望操作的新线程。在请求完成并将结果返回给用户之前是否需要等待该线程终止。

附:如果没有用户,线程的执行时间可能会增加。

如果可能,请提出任何替代方案

程序逻辑(目前我正在使用 await 函数等待异步函数执行)

public async Task<IHttpActionResult> doSomething(arguments)
{  
    .
    .
    .
    .
    <!-- Perform some operation which includes some database transcations--!>

    if(operation succesed)
    {
        await Notification(userid);
    }

    return result;
}

【问题讨论】:

  • 请显示您的代码 - 如何启动线程、如何通知用户以及如何等待线程终止
  • @SergeyBerezovskiy 我用程序逻辑更新了问题。如果你清楚,请告诉我

标签: c# asp.net multithreading thread-safety asp.net-web-api2


【解决方案1】:
static void Main(string[] args)
{
    var userIds = new[] { 1, 2, 3, 4, 5};

    Console.WriteLine("Updating db for users...");

    // Start new thread for notficiation send-out
    Task.Run(() =>
    {
        foreach (var i in userIds)
            Console.WriteLine("Sending notification for #user " + i);

    }).ContinueWith(t => Console.WriteLine("Notifcation all sent!"));

    Console.WriteLine("Return the result before notification all sent out!");
}

如果您删除 Task.Run() 前面的 await(相当于 Notifcation() 在您的情况下返回 Task)并运行,那么它将为通知发送创建单独的线程。

【讨论】:

    【解决方案2】:
    public async Task<IHttpActionResult> doSomething(arguments)
        {  
         bool isInsertDone ,isUpdateDone = false;
    
         //create thread list
          var task = new List<Task>();
    
          // parallel tasks to thread list and execute that tasks 
           task.Add(Task.Run(() =>
              {`enter code here`
                  isInsertDone = insertData(arguments)
               }));
               task.Add(Task.Run(() =>
               {
                  isUpdateDone  updateData(arguments)
               }));
    
            // wait for execute all above tasks
             Task.WaitAll(task.ToArray());
    
            // return response by result of insert and update.
            return Ok<bool>(isInsertDone && isUpdateDone);
        }
    

    【讨论】:

      【解决方案3】:

      如果它是一个长时间运行的函数,并且对当前函数没有直接影响,则无需等待。开火然后忘记。您可以安全地删除 await。

      public async Task<IHttpActionResult> doSomething(arguments) {  
          //... Perform some operation which includes some async database transactions
      
          if(operation succesed) {
              NotificationsAsync(userid); //Start notifications and continue
          }
      
          return result;
      }
      

      我建议对此类作业使用消息队列,但这是一个更高级的主题,超出了本问题的范围。

      【讨论】:

      • 删除等待后它给我警告说线程不完整通知函数使用控制器中定义的 dbcontext,所以我需要为函数创建本地 dbcontext 实例
      • 是的,编译器会显示警告,但它可以工作。
      • 好的,感谢@Nkosi 抽出宝贵时间
      猜你喜欢
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 2015-04-17
      • 2021-10-31
      • 2015-04-17
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多