question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[OfficeDevPnP.Core] Threadpool issue in AuthenticationManager().GetAppOnlyAuthenticatedContext(...)

See original GitHub issue

Hi

We noticed errors in Azure webjobs that ran this code in big for loops (i.e. customer has thousands of sites to manage). I managed to reproduce this locally:

There were not enough free threads in the ThreadPool to complete the operation

Which is caused by:

using (var context = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, clientId, clientSecret))

A thread is being created to account for access token renewal it seems (‘EnsureToken’, see screenshot below): https://github.com/pnp/PnP-Sites-Core/blob/master/Core/OfficeDevPnP.Core/AuthenticationManager.cs#L326

wi.Handle = ThreadPool.RegisterWaitForSingleObject(appOnlyAccessTokenResetEvent, ...);

Although there does seem to be a dispose method that should release the thread when exiting the using curly braces: https://github.com/pnp/PnP-Sites-Core/blob/master/Core/OfficeDevPnP.Core/AuthenticationManager.cs#L1496

It can be easily reproduced by creating a console app (.NET 4.7.2), installing NuGet package ‘SharePointPnPCoreOnline’ version 3.18.2002. The code can be found below. Open up the Threads window during a debug session (Debug > Windows > Threads) and you will see a surplus thread per context that has been created, despite the using statement (or .dispose() method). This can be seen in the screenshot below. At a certain moment in time, the maximum available threads are exhausted, which causes the error.

How can I update the this piece of (legacy) code to avoid this error?

I don’t think there is something inherently wrong with the sample script, that is a perfectly viable way to go about processing multiple sites using CSOM. Correct me if I’m wrong.

The fact remains that we need to iterate over thousands of different sites and perform 1 or 2 csom calls on them, to set some SP settings.

` using Microsoft.SharePoint.Client; using OfficeDevPnP.Core;

namespace OfficeDevPnPAuthManagerThreadIssue
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var siteUrl = "https://***.sharepoint.com/sites/kyataccount";
            var clientId = "*****";
            var clientSecret = "***";

            for (int i = 0; i < 50; i++)
            {
                using (var context = new AuthenticationManager()
                    .GetAppOnlyAuthenticatedContext(siteUrl, clientId, clientSecret))
                {
                    var web = context.Web;
                    context.Load(web, w => w.Title);
                    context.ExecuteQueryRetry();
                    var title = web.Title;

                    if(40 == i)
                    {
                        var breakPoint = "put breakpoint here";
                    }
                }
            }
        }
    }
}`

image

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
PieterHeemeryckcommented, Jan 20, 2022

@patrikhellgren, the Clone method seems to work as you mentioned! Only a single thread is used for this. Thanks!

1reaction
patrikhellgrencommented, Jan 20, 2022

@PieterHeemeryck Try to use context.Clone(newSiteUrl) instead, that will not get a new token as long as it is within the same host and as I understand it you will be. So something like this:

var context = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, clientId, clientSecret);
for (int i = 0; i < 50; i++)
{
  using(var clonedContext = context.Clone(siteUrl))
  {
    var web = clonedContext.Web;
    clonedContext.Load(web, w => w.Title);
    clonedContext.ExecuteQueryRetry();
    var title = web.Title;
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Unable to use “OfficeDevPnP.Core.AuthenticationManager ...
Unable to use “OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext” inside ASP.NET core (.NET 5).
Read more >
Multithreading bug in OfficeDevPnP.Core. ...
Steps to Reproduce. Obtain an app token and ClientContext by calling AuthenticationManager.GetAppOnlyAuthenticatedContext; Wait until 4 minutes ...
Read more >
Problem with threads count grow when use OfficeDevPnP ...
Recently we faced with the following problem in our Azure function app: ... Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(url ...
Read more >
OfficeDevPnP.Core AuthenticationManager ...
Unfortunately GetAppOnlyAuthenticatedContext works only with low-trust apps and uses AzureACS in order to obtain access token.
Read more >
Sharepoint 365 allowing me to only write two items then ...
Modifying the authentication using OfficeDevPnP.Core.AuthenticationManager, ClientID and ClientSecret I can get the access token. I can then do ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found