C# . NET线程正在中止异常

C# . NET线程正在中止异常,c#,.net,asp.net-web-api,C#,.net,Asp.net Web Api,我有一个ASP.NET MVC API调用,它启动了在后台运行Parallel.forEach的任务。forEach运行10个并发任务,为我们传递给它的数据列表做它需要做的事情 至于API调用,我们只需将Ok(result)返回到前端,因为我只希望此任务在后台运行。完成后会通知我的 我想既然任务之间不相互依赖,我可以通过一次启动10个任务来加快这个过程,当该批任务完成后,再启动下10个任务,以此类推 DoLongRunningProcess()中的进程可能需要5秒到7分钟 这是我的问题。在DoL

我有一个ASP.NET MVC API调用,它启动了在后台运行
Parallel.forEach
的任务。forEach运行10个并发任务,为我们传递给它的数据列表做它需要做的事情

至于API调用,我们只需将
Ok(result)
返回到前端,因为我只希望此任务在后台运行。完成后会通知我的

我想既然任务之间不相互依赖,我可以通过一次启动10个任务来加快这个过程,当该批任务完成后,再启动下10个任务,以此类推

DoLongRunningProcess()
中的进程可能需要5秒到7分钟

这是我的问题。在
DoLongRunningProcess()
方法的某个地方,我们得到了一个异常“Thread was being aborted”,它似乎突破了
parallel.ForEach
,并在
RunMyParallelLoop()
方法中被捕获到异常

更大的问题是,当我们有150多条记录要处理时,它会随机发生。有时该任务将顺利运行,有时具有相同数据的同一任务将在
Parallel.ForEach
的10个批中的一个批中引发“Thread was being aborted”异常

现在,这可能是一个糟糕的/不干净的方法,所以这就是为什么我期待社区的帮助

我错过了什么

下面的代码示例

public IHttpActionResult MyMvcApiCall()
{
   MyService ms = new MyService()
   ms.CreateTaskAndStartprocess(someData)

   result = new {message: "Your process has started"};
   return Ok(result)
}

//MyService.cs
public CreateTaskAndStartprocess(SomeData someData)
{
   Task.Run(() => {
      RunMyParallelLoop(someData);
   });
}

private RunMyParallelLoop (SomeData someData)
{
   try
   {
      var options = new ParallelOptions {MaxDegreeOfParallelism = 10};
      var exceptions = new ConcurrentQueue<Exception>();

      Parallel.ForEach( someData, options, dataItem => 
      {
         try
         {
            DoLongRunningProcess(dataItem);
         } 
         catch (Exception e)
         {
           //used to track any issues within DoLongRunningProcess
           exceptions.Enqueue(e);
         }
      }
   }
   catch (Exception e)
   {
      //ThreadAbortException in DoLongRunningProcess seems to break out of Parallel.ForEach up to hear
      // Other Exceptions in DoLongRunningProcess do not bubble up to here
      LogError(e);
      throw
   }
}

private DoLongRunningProcess(dataItem)
{
    try
    {
       updateStatusOfDataItemInDb("in porogress");
       createByteArrayToCreateFile()
       DoSomeIO()
       updateStatusOfDataItemInDb("done");
    }
    catch (Exception e)
    {
       updateStatusOfDataItemInDb("failed");
       throw;
    }
}
public IHttpActionResult MyMvcApiCall()
{
MyService ms=newmyservice()
ms.CreateTaskAndStartprocess(someData)
结果=新建{消息:“您的进程已启动”};
返回Ok(结果)
}
//MyService.cs
公共CreateTask和StartProcess(SomeData SomeData)
{
Task.Run(()=>{
运行MyParallelLoop(someData);
});
}
私有RunMyParallelLoop(SomeData SomeData)
{
尝试
{
var options=new ParallelOptions{maxdegreeofpparallelism=10};
var exceptions=新的ConcurrentQueue();
Parallel.ForEach(someData,options,dataItem=>
{
尝试
{
多龙运行过程(数据项);
} 
捕获(例外e)
{
//用于跟踪DoLongRunningProcess中的任何问题
例外情况。排队(e);
}
}
}
捕获(例外e)
{
//DoLongRunningProcess中的ThreadAbortException似乎打破了并行。ForEach up to hear
//DoLongRunningProcess中的其他异常不会出现在这里
对数误差(e);
扔
}
}
私有DoLongRunningProcess(数据项)
{
尝试
{
更新StatusOfDataItemIndb(“在porogress中”);
createByteArrayToCreateFile()
多索米奥()
updateStatusOfDataItemInDb(“完成”);
}
捕获(例外e)
{
updateStatusOfDataItemInDb(“失败”);
投掷;
}
}
你不能(安全地)从像ASP.NET那样的请求开始后台任务。你应该看看
IHostedService
,它确实可以让你(稍微)安全地完成任务,然后从托管服务的请求和进程中添加某种生产者-消费者队列。我说“稍微”安全,因为这毕竟是一个可以随时终止的web应用程序。