Not the ambient scope error when calling Umbraco ContentService methods
Hello,
I am having an intermittent error within some import code that we have, which loads content from a spreadsheet and populates into Umbraco using the ContentService.
Sometimes, intermittently, the content service throws an error "System.InvalidOperationException: Not the ambient scope." which I will copy excerpts from the logs below.
I am trying to put together a minimal test case showing the problem that I could share. But raising this just in case one of you clever folk know what we are doing wrong from this description:
ascx "import" user control added to dashboard.config - user uploads file and triggers import from this
we make a new Thread to do the import in the background, passing in HttpContext.Current, and within the thread we set HttpContext.Current to the context passed in, this was needed to still be able to use Umbraco api
Inside this thread we call "ApplicationContext.Current.Services.ContentService.GetById" and at this point it errors
It tends to work once and then if you try again straight after it errors. I'm sure it is something to do with objects being disposed, but I don't know what this Ambient Scope stuff is.
This is what appears in the logs:
2018-11-15 10:12:52,361 [P30904/D4/T14] ERROR Umbraco.Web.UmbracoModule - Could not dispose item with key Umbraco.Core.Scoping.ScopeReference
System.NullReferenceException: Object reference not set to an instance of an object.
at Umbraco.Core.Persistence.Database.CleanupTransaction()
at Umbraco.Core.Persistence.Database.AbortTransaction()
at Umbraco.Core.Scoping.Scope.DisposeLastScope()
at Umbraco.Core.Scoping.Scope.Dispose()
at Umbraco.Core.Scoping.ScopeReference.Dispose()
at Umbraco.Core.ObjectExtensions.DisposeIfDisposable(Object input)
at Umbraco.Web.UmbracoModule.DisposeHttpContextItems(HttpContext http)
2018-11-15 10:12:52,406 [P30904/D4/T48] ERROR Core.Repositories.UmbracoExceptionLogger - UmbracoImportService.ImportWorkbooks(1072, False, 1)
System.InvalidOperationException: Not the ambient scope.
at Umbraco.Core.Scoping.Scope.Dispose()
at Umbraco.Core.Persistence.UnitOfWork.ScopeUnitOfWork.DisposeResources()
at Umbraco.Core.DisposableObjectSlim.Dispose(Boolean disposing)
at Umbraco.Core.DisposableObjectSlim.Dispose()
at Umbraco.Core.Services.ContentService.GetById(Int32 id)
at Core.Services.UmbracoImportService.ImportWorkbooks(IList`1 workbooks, Int32 regionNodeId, Boolean isOnlyValidation, Int32 umbracoUserId) in UmbracoImportService.cs:line 260
From reviewing the source of umbraco.dll it appears to be because Umbraco.Web.UmbracoModule.Init registers an OnEndRequest handler which calls UmbracoModule.DisposeHttpContextItems which calls Dispose on anything in HttpContext.Item cache that implements Umbraco.Core.IDisposeOnRequestEnd.
Presumably when my initial web request ends, this method is run and it cleans up various things that are still being referenced by the HttpContext within my Thread. The following classes implement IDisposeOnRequestEnd: Umbraco.Web.UmbracoContext and Umbraco.Core.Scoping.ScopeReference.
I think I need to remove this work from background thread, or at least remove the need to copy the HttpContext over. Surprised there is no way to call the Services without a HttpContext.
This might be a solution, although I don't much like the idea of having to run background tasks on a fake web request. Maybe can use the Umbraco Task scheduler to trigger it.
Not the ambient scope error when calling Umbraco ContentService methods
Hello,
I am having an intermittent error within some import code that we have, which loads content from a spreadsheet and populates into Umbraco using the ContentService.
Sometimes, intermittently, the content service throws an error "System.InvalidOperationException: Not the ambient scope." which I will copy excerpts from the logs below.
I am trying to put together a minimal test case showing the problem that I could share. But raising this just in case one of you clever folk know what we are doing wrong from this description:
It tends to work once and then if you try again straight after it errors. I'm sure it is something to do with objects being disposed, but I don't know what this Ambient Scope stuff is.
This is what appears in the logs:
Many thanks for any ideas you may have.
Andy
From reviewing the source of umbraco.dll it appears to be because Umbraco.Web.UmbracoModule.Init registers an OnEndRequest handler which calls UmbracoModule.DisposeHttpContextItems which calls Dispose on anything in HttpContext.Item cache that implements Umbraco.Core.IDisposeOnRequestEnd.
Presumably when my initial web request ends, this method is run and it cleans up various things that are still being referenced by the HttpContext within my Thread. The following classes implement IDisposeOnRequestEnd: Umbraco.Web.UmbracoContext and Umbraco.Core.Scoping.ScopeReference.
I think I need to remove this work from background thread, or at least remove the need to copy the HttpContext over. Surprised there is no way to call the Services without a HttpContext.
This might be a solution, although I don't much like the idea of having to run background tasks on a fake web request. Maybe can use the Umbraco Task scheduler to trigger it.
https://our.umbraco.com/forum/developers/api-questions/54671-UmbracoContext-in-New-Thread-to-Populate-Cache-Asynchronously
Also this describes my failure in the first two pitfalls: https://our.umbraco.com/documentation/Reference/Common-Pitfalls/
Ok it looks like the ContentService didn't need the HttpContext after all. Have to comment out all my HttpContext hacks and see where it was required.
is working on a reply...