IPublishedContent children cannot access a dispose...
# help-with-other
j
I have a controller using System.Threading.Tasks.Task to build a zip folder. Inside the Task I'm using a scoped service. I tried IServiceScopeFactory.CreateScope() and IUmbracoContextFactory.EnsureUmbracoContext() but it keep error on disposed. Please help https://cdn.discordapp.com/attachments/1238591486086615130/1238591486262771772/Screenshot_2024-05-10_153653.png?ex=663fd7b6&is=663e8636&hm=338e8d3f28fd8a890c073f7a548116d808e095faea5d71133ba962dc3ed523b0&
Copy code
foreach (...)
{
  runningTasks[indx] = new System.Threading.Tasks.Task(() =>
  {
    using (var scope = _serviceScopeFactory.CreateScope())
    {
      using (var context = _umbracoContextFactory.EnsureUmbracoContext())
      {
        // sheetItem is IPublishedContent

        var myService = scope.ServiceProvider.GetRequiredService<MyService>();
        var value = myService.DoSomething(sheetItem);
      }
    }
  }

  runningTasks[indx].Start();
  indx++;
}

System.Threading.Tasks.Task.WaitAll(runningTasks);
In MyService I injected EF Core Context so it's a scoped service. Is possible to run in multithreaded?
m
The context is created then disposed within the loop. You only need 1 wrapping the loop
j
Do you mean keep scope at the same position but move context outside the loop?
m
Yes, as the sheetItem.Children is query the context cache as it's a lazy property
j
I moved context outside the loop but still got the same error
Copy code
using (var context = _umbracoContextFactory.EnsureUmbracoContext())
{
  foreach (...)
  {
    runningTasks[indx] = new System.Threading.Tasks.Task(() =>
    {
      using (var scope = _serviceScopeFactory.CreateScope())
      {
          // sheetItem is IPublishedContent
          // MyService is a scoped service injected EF Context
  
          var myService = scope.ServiceProvider.GetRequiredService<MyService>();
          var value = myService.DoSomething(sheetItem);
      }
    }
  
    runningTasks[indx].Start();
    indx++;
  }
  
  System.Threading.Tasks.Task.WaitAll(runningTasks);
}
Here is the new code.
36 Views