Pour obtenir une clé
d'essai remplissez le formulaire ci-dessous
Demandez des tariffs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
* En cliquant sur ce bouton, vous acceptez notre politique de confidentialité

Free PVS-Studio license for Microsoft MVP specialists
To get the licence for your open-source project, please fill out this form
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

I am interested to try it on the platforms:
** En cliquant sur ce bouton, vous acceptez notre politique de confidentialité.

Votre message a été envoyé.

Nous vous répondrons à

Si vous n'avez toujours pas reçu de réponse, vérifiez votre dossier
Spam/Junk et cliquez sur le bouton "Not Spam".
De cette façon, vous ne manquerez la réponse de notre équipe.

Roslyn API: why PVS-Studio was analyzin…

Roslyn API: why PVS-Studio was analyzing the project so long

22 Avr 2021

How many of you have used third-party libraries when writing code? It's a catchy question. Without third-party libraries the development of some products would be delayed for a very, very long time. One would have to reinvent the wheel to solve each problem. When you use third-party libraries you still stumble upon some pitfalls in addition to obvious advantages. Recently PVS-Studio for C# has also faced one of the deficiencies. The analyzer could not finish analyzing a large project for a long time. It was due to the use of the SymbolFinder.FindReferencesAsync method from the Roslyn API in the V3083 diagnostic.


Life in PVS-Studio was going on as usual. We kept on writing new diagnostics, improving the analyzer, posting new articles. Bang! One of the analyzer users had the analysis going on a large project during the day and could not end in any way. Alarm! Alarm! All hands on deck! After getting dump files from the user we shifted our focus to find out the reasons for long analysis. It turned out that 3 C# diagnostics worked the longest. One of them was the diagnostic number V3083. This diagnostic has already had our special attention. The time has come to take specific actions! V3083 warns about incorrect C# event calls. For example, in the code:

public class IncorrectEventUse
  public event EventHandler EventOne;  
  protected void InvokeEventTwice(object o, Eventers args)
    if (EventOne != null)
      EventOne(o, args);        
      EventOne.Invoke(o, args);

V3083 will point to calls to event handlers of EventOne in the InvokeEventTwice method. You can learn more about the reasons why this code is dangerous in this diagnostic's documentation. From the outside, the logic of the V3083 is very simple:

  • find an event call;
  • check if this event is called correctly;
  • issue a warning if the event is called incorrectly.

Now when we know that it is so simple, it becomes even more interesting to get the reason for the long diagnostic work.

Reason for the slowdown

In fact, the logic is a little more complicated. In each file for each type V3083 creates only one analyzer warning for an event. In this warning, V3083 writes all line numbers of cases when the event is incorrectly called. This helps to navigate in various plugins: Visual Studio, Rider, SonarQube. It turns out that the first step is to find all the places where the event is called. For a similar task, Roslyn API already had the SymbolFinder.FindReferencesAsync method. It was used in V3083, so as not to reinvent the wheel.

Many guidelines recommend using this method: first, second, third [RU] and others. Perhaps, in some simple cases, the speed of this method is enough. However, the larger the project's codebase, the longer this method will run. We were 100% sure of this only after changing V3083.

V3083 speed up after the change

If you change a diagnostic's code or the analyzer core, you need to check that nothing that worked before is broken. To do this, we have positive and negative tests for each diagnostic, unit tests for the analyzer core, as well as a database of open-source projects. There are almost 90 projects in it. Why do we need a database of open-source projects? We use it to run our analyzer to test the tool in field conditions. Also this run serves as an additional check that we have not broken anything in the analyzer. We already had a run of the analyzer on this base before the V3083 change. All we had to do is to make a similar run after changing V3083 and figure out the time gain. The results turned out to be a pleasant surprise! We got a 9% speedup on tests without using SymbolFinder.FindReferencesAsync. These figures might seem insignificant to someone. Well, check out the specs of the computer that we used for measurements:


Hopefully even the most cynical skeptics have fully realized the scale of the problem that lived quietly in the V3083 diagnostic.


Let this note be a warning to everyone who uses the Roslyn API! This way you will not make our mistakes. Not only does this apply to the SymbolFinder.FindReferencesAsync method. It is also about other Microsoft.CodeAnalysis.FindSymbols.SymbolFinder class methods that use the same mechanism.

I also highly recommend that all developers review libraries they use. I say this for a reason! Why is it so important? Check out our other notes to find out why: first, second. They cover this topic in more detail.

Apart from developing diagnostics we've been busy optimizing PVS-Studio. Don't miss future articles and notes to find out about changes!

We haven't released the V3083 diagnostic fix, therefore the analyzer version 7.12 works using SymbolFinder.FindReferencesAsync.

As I mentioned earlier, we found the analyzer slowdown in two other C# diagnostics besides V3083. How do you think, which ones are these diagnostics? Just for the sake of interest, leave your ideas in comments. When there are more than 50 suggestions, I will open the veil of secrecy and call the numbers of these diagnostics.

Popular related articles
Sorting in C#: OrderBy.OrderBy or OrderBy.ThenBy? What's more effective and why?

Date: 20 Sep 2022

Author: Sergey Vasiliev

Suppose we need to sort the collection by multiple keys. In C#, we can do this with the help of OrderBy().OrderBy() or OrderBy().ThenBy(). But what is the difference between these calls? To answer th…
ML.NET: can Microsoft's machine learning be trusted?

Date: 08 Sep 2022

Author: Andrey Moskalev

In 2018, Microsoft created ML.NET, a machine learning framework for .NET developers. Since then, the machine learning library has undergone significant changes and acquired new features to identify p…
The risks of using vulnerable dependencies in your project, and how SCA helps manage them

Date: 06 Sep 2022

Author: Nikita Lipilin

Most applications today use third-party libraries. If such a library contains a vulnerability, an app that uses this library may also be vulnerable. But how can you identify such problematic dependen…
Build to order? Checking MSBuild for the second time

Date: 01 Sep 2022

Author: Nikita Panevin

MSBuild is a popular open-source build platform created by Microsoft. Developers all over the world use MSBuild. In 2016, we checked it for the first time and found several suspicious places. Can we …
The Orchard Core threequel. Rechecking the project with PVS-Studio

Date: 25 Aoû 2022

Author: Aleksey Avdeev

In this article, we check the Orchard Core project with the help of the PVS-Studio static analyzer. We are going to find out if the platform code is as good as the sites created on its basis. May the…

Comments (0)

Next comments
Unicorn with delicious cookie
Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus