Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ahmed Ennab 1 post 71 karma points
    Nov 09, 2023 @ 13:24
    Ahmed Ennab
    0

    The Scope being disposed is not the Ambient Scope

    Hello,

    I am on Umbraco v12.1.1 I am trying to create content programmatically, I was able to do it for one culture but I would also like to create the same content for all cultures (for now)

    Please keep in mind I have no Tasks or Async code, this is all synchronous

    The behaviour is unexpected, it usually breaks for the 2nd culture and 50% of the documents.

    Code snippet

    private IContent? AddOrUpdateCategoryNode(CategoryDto category, IContent parentNode, string brandDocId)
    {
        try
        {
            IContent? newNode = _contentService.Create(category.Name, parentNode.Id, Application.ModelTypeAlias);
            string imagesBlock = string.Empty;
            imagesBlock = BlockListFactory.Create(_contentTypeService, category.Images, image => new Dictionary<string, string>() {
                    {"imageUrl", image.Url},
                    {"imageAltText", image.Alt}
            }, ProductImageItem.ModelTypeAlias).ToString();
    
            foreach (var culture in cultures)
            {
                newNode.SetCultureName(category.Name, culture);
    
                newNode.SetValue("brands", string.Join(",", brandDocId), culture);
                if (!string.IsNullOrEmpty(imagesBlock)) newNode.SetValue("images", imagesBlock.ToString(), culture);
    
                _contentService.SaveAndPublish(newNode,culture);
            }
    
            return newNode;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error while creating node for category {category.Name}.");
            return null;
        }
    }
    

    It breaks when it hits SaveAndPublish()

    Exception trace

    {"The Scope 5f2261f0-8e97-4e8c-a540-0d69949895e8 being disposed is not the Ambient Scope 477ed48a-1c75-4be4-b607-7b9f5d020aea. This typically indicates that a child Scope was not disposed, or flowed to a child thread that was not awaited, or concurrent threads are accessing the same Scope (Ambient context) which is not supported. If using Task.Run (or similar) as a fire and forget tasks or to run threads in parallel you must suppress execution context flow with ExecutionContext.SuppressFlow() and ExecutionContext.RestoreFlow()."}

    What I have tried:

    1. Creating a scope using both IScopeProvider and ICoreScopeProvider (and placing it inside the foreach, outside the foreach as well as outside the whole function)
    2. Using ExecutionContext.SuppressFlow(), this just results in freezing SaveAndPublish() - I have also tried placing it everywhere, no luck
    3. Setting the values then using SaveAndPublish() with a wildcard culture
    4. Not setting the culture name

    I have tried many more things but no luck, couldn't find much information on it. Am I setting the values for multiculture incorrectly or is it a bug?

  • Daniël Knippers 153 posts 1116 karma points MVP 2x c-trib
    Feb 07, 2024 @ 09:23
    Daniƫl Knippers
    0

    Hi Ahmed,

    We also run into this exception in an Umbraco v10 site when we run jobs from Hangfire (a background task scheduler). What fixed this for us is to use ExecutionContext.SuppressFlow() (mentioned in the exception) together with Task.Run().

    Try it like this:

    using (ExecutionContext.SuppressFlow())
    {
        return Task.Run(() => 
        {
            // Your code here
        });
    }
    

    Hope this helps! It is very unfortunate Umbraco requires this strange mechanism when calling their code from background threads though.

  • michal18q 1 post 21 karma points
    6 days ago
    michal18q
    0

    Hi All,

    I know it's quite late, but in case anyone else steps upon that problem, we were able to fix it by surrounding _contentService.SaveAndPublish(newNode,culture); with the following code:

    using (var scope = _scopeProvider.CreateScope(autoComplete: true))
    {
       using (var ctx = _umbracoContextFactory.EnsureUmbracoContext())
       {
          _contentService.SaveAndPublish(newNode);
       }
    }
    

    where _scoperProvider is an instance of Umbraco.Cms.Infrastructure.Scoping.IScopeProvider and _umbracoContextFactory is an instance of Umbraco.Cms.Core.Web.IUmbracoContextFactory

Please Sign in or register to post replies

Write your reply to:

Draft