Threading issue in ASP.NET Core










-2















I have an ASP.NET Core Web API project. That has one controller with a method called GetLocations



GetLocations connects to 5 other web services on the internet. Gathers some info and return a collection via json. In this method I am caching the data every 5 mins using In Memory caching.



If the cache expires, it tries to connect to all 5 services and get the info and so on.



My problem is:



I have a lot of users requesting this data constantly, 50 requests a second to this API.



When the cache expires I believe there is some kind of thread locking. I have limited visibility into the project at the moment but I suspect that all these requests are calling the method and reaching out to the 5 dependent services until one of them gets a completed response from all 5.



Is my assumption right? If so how can I go about fixing this? Will I need to make each call to the web services async? Will that help this scenario? I am not 100% sure because the requests are what triggers the method call.










share|improve this question

















  • 1





    "Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

    – zerkms
    Nov 14 '18 at 1:00






  • 1





    It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

    – mjwills
    Nov 14 '18 at 1:03











  • When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

    – Poul Bak
    Nov 14 '18 at 2:07















-2















I have an ASP.NET Core Web API project. That has one controller with a method called GetLocations



GetLocations connects to 5 other web services on the internet. Gathers some info and return a collection via json. In this method I am caching the data every 5 mins using In Memory caching.



If the cache expires, it tries to connect to all 5 services and get the info and so on.



My problem is:



I have a lot of users requesting this data constantly, 50 requests a second to this API.



When the cache expires I believe there is some kind of thread locking. I have limited visibility into the project at the moment but I suspect that all these requests are calling the method and reaching out to the 5 dependent services until one of them gets a completed response from all 5.



Is my assumption right? If so how can I go about fixing this? Will I need to make each call to the web services async? Will that help this scenario? I am not 100% sure because the requests are what triggers the method call.










share|improve this question

















  • 1





    "Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

    – zerkms
    Nov 14 '18 at 1:00






  • 1





    It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

    – mjwills
    Nov 14 '18 at 1:03











  • When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

    – Poul Bak
    Nov 14 '18 at 2:07













-2












-2








-2








I have an ASP.NET Core Web API project. That has one controller with a method called GetLocations



GetLocations connects to 5 other web services on the internet. Gathers some info and return a collection via json. In this method I am caching the data every 5 mins using In Memory caching.



If the cache expires, it tries to connect to all 5 services and get the info and so on.



My problem is:



I have a lot of users requesting this data constantly, 50 requests a second to this API.



When the cache expires I believe there is some kind of thread locking. I have limited visibility into the project at the moment but I suspect that all these requests are calling the method and reaching out to the 5 dependent services until one of them gets a completed response from all 5.



Is my assumption right? If so how can I go about fixing this? Will I need to make each call to the web services async? Will that help this scenario? I am not 100% sure because the requests are what triggers the method call.










share|improve this question














I have an ASP.NET Core Web API project. That has one controller with a method called GetLocations



GetLocations connects to 5 other web services on the internet. Gathers some info and return a collection via json. In this method I am caching the data every 5 mins using In Memory caching.



If the cache expires, it tries to connect to all 5 services and get the info and so on.



My problem is:



I have a lot of users requesting this data constantly, 50 requests a second to this API.



When the cache expires I believe there is some kind of thread locking. I have limited visibility into the project at the moment but I suspect that all these requests are calling the method and reaching out to the 5 dependent services until one of them gets a completed response from all 5.



Is my assumption right? If so how can I go about fixing this? Will I need to make each call to the web services async? Will that help this scenario? I am not 100% sure because the requests are what triggers the method call.







c# async-await






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 0:58









TheWebGuyTheWebGuy

2,448103952




2,448103952







  • 1





    "Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

    – zerkms
    Nov 14 '18 at 1:00






  • 1





    It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

    – mjwills
    Nov 14 '18 at 1:03











  • When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

    – Poul Bak
    Nov 14 '18 at 2:07












  • 1





    "Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

    – zerkms
    Nov 14 '18 at 1:00






  • 1





    It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

    – mjwills
    Nov 14 '18 at 1:03











  • When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

    – Poul Bak
    Nov 14 '18 at 2:07







1




1





"Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

– zerkms
Nov 14 '18 at 1:00





"Is my assumption right?" --- given you provided literally nothing it may be with equal probability: Yes/No/May be.

– zerkms
Nov 14 '18 at 1:00




1




1





It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

– mjwills
Nov 14 '18 at 1:03





It would be awesome if you could provide a Minimal, Complete, and Verifiable example.

– mjwills
Nov 14 '18 at 1:03













When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

– Poul Bak
Nov 14 '18 at 2:07





When updating, I would create a temp cache, that, when finished is copied to the live system, then system will be slow for a very short time.

– Poul Bak
Nov 14 '18 at 2:07












2 Answers
2






active

oldest

votes


















0














You should definitely make the calls to the external services use Async / Await.



That's just a given - as the best practice is to always use async for I/O heavy operations (such as calling a third-party service).



Now, you should also create a class that manages these calls. You can add it as a Singleton in your IoCConfig. In that class, make sure you're "locking" to avoid the issue you just described and not call the underlying services numerous times while the cache is being built.



Check here:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement






share|improve this answer




















  • 1





    "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

    – zerkms
    Nov 14 '18 at 1:05



















0














You are facing this issue because of following reason.



  1. You are using Cache and it will expire at some definite time.

  2. After Cache expire you call external web service method to collect the data. Now at this point of time it might happen that other request in queue get choose for execution.

  3. Once that another request is chosen for execution it also end up checking cache and it now data in cache then execute external service and so on for other request.

Solution to this.



  1. First Check cache contains data or not.

  2. If Not create lock so following section only be executed by single thread.

  3. Now in that lock section again check for cache and if cache contains data then simply return but it does not contains then call external service.

  4. At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.

  5. Once that section get completed it store data in cache and so after if any queued or new request is there it choose data from cache.

Note : It should something like this.



 public List<string> GetData()

if(Cache[key] == null)

lock(obj) // obj should be static

if(Cache[key] == null)

// Load data from service
Cache[key] == data;



return (List<string>)Cache[Key];






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291675%2fthreading-issue-in-asp-net-core%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You should definitely make the calls to the external services use Async / Await.



    That's just a given - as the best practice is to always use async for I/O heavy operations (such as calling a third-party service).



    Now, you should also create a class that manages these calls. You can add it as a Singleton in your IoCConfig. In that class, make sure you're "locking" to avoid the issue you just described and not call the underlying services numerous times while the cache is being built.



    Check here:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement






    share|improve this answer




















    • 1





      "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

      – zerkms
      Nov 14 '18 at 1:05
















    0














    You should definitely make the calls to the external services use Async / Await.



    That's just a given - as the best practice is to always use async for I/O heavy operations (such as calling a third-party service).



    Now, you should also create a class that manages these calls. You can add it as a Singleton in your IoCConfig. In that class, make sure you're "locking" to avoid the issue you just described and not call the underlying services numerous times while the cache is being built.



    Check here:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement






    share|improve this answer




















    • 1





      "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

      – zerkms
      Nov 14 '18 at 1:05














    0












    0








    0







    You should definitely make the calls to the external services use Async / Await.



    That's just a given - as the best practice is to always use async for I/O heavy operations (such as calling a third-party service).



    Now, you should also create a class that manages these calls. You can add it as a Singleton in your IoCConfig. In that class, make sure you're "locking" to avoid the issue you just described and not call the underlying services numerous times while the cache is being built.



    Check here:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement






    share|improve this answer















    You should definitely make the calls to the external services use Async / Await.



    That's just a given - as the best practice is to always use async for I/O heavy operations (such as calling a third-party service).



    Now, you should also create a class that manages these calls. You can add it as a Singleton in your IoCConfig. In that class, make sure you're "locking" to avoid the issue you just described and not call the underlying services numerous times while the cache is being built.



    Check here:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 14 '18 at 1:11

























    answered Nov 14 '18 at 1:03









    turtlepickturtlepick

    2,4601722




    2,4601722







    • 1





      "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

      – zerkms
      Nov 14 '18 at 1:05













    • 1





      "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

      – zerkms
      Nov 14 '18 at 1:05








    1




    1





    "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

    – zerkms
    Nov 14 '18 at 1:05






    "to always use async for I/O heavy operations" --- async is not free, you may have cases when blocking IO is preferred due to performance requirements. I agree that in general async might be a default choice, my point is that "always" is a strong word here.

    – zerkms
    Nov 14 '18 at 1:05














    0














    You are facing this issue because of following reason.



    1. You are using Cache and it will expire at some definite time.

    2. After Cache expire you call external web service method to collect the data. Now at this point of time it might happen that other request in queue get choose for execution.

    3. Once that another request is chosen for execution it also end up checking cache and it now data in cache then execute external service and so on for other request.

    Solution to this.



    1. First Check cache contains data or not.

    2. If Not create lock so following section only be executed by single thread.

    3. Now in that lock section again check for cache and if cache contains data then simply return but it does not contains then call external service.

    4. At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.

    5. Once that section get completed it store data in cache and so after if any queued or new request is there it choose data from cache.

    Note : It should something like this.



     public List<string> GetData()

    if(Cache[key] == null)

    lock(obj) // obj should be static

    if(Cache[key] == null)

    // Load data from service
    Cache[key] == data;



    return (List<string>)Cache[Key];






    share|improve this answer



























      0














      You are facing this issue because of following reason.



      1. You are using Cache and it will expire at some definite time.

      2. After Cache expire you call external web service method to collect the data. Now at this point of time it might happen that other request in queue get choose for execution.

      3. Once that another request is chosen for execution it also end up checking cache and it now data in cache then execute external service and so on for other request.

      Solution to this.



      1. First Check cache contains data or not.

      2. If Not create lock so following section only be executed by single thread.

      3. Now in that lock section again check for cache and if cache contains data then simply return but it does not contains then call external service.

      4. At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.

      5. Once that section get completed it store data in cache and so after if any queued or new request is there it choose data from cache.

      Note : It should something like this.



       public List<string> GetData()

      if(Cache[key] == null)

      lock(obj) // obj should be static

      if(Cache[key] == null)

      // Load data from service
      Cache[key] == data;



      return (List<string>)Cache[Key];






      share|improve this answer

























        0












        0








        0







        You are facing this issue because of following reason.



        1. You are using Cache and it will expire at some definite time.

        2. After Cache expire you call external web service method to collect the data. Now at this point of time it might happen that other request in queue get choose for execution.

        3. Once that another request is chosen for execution it also end up checking cache and it now data in cache then execute external service and so on for other request.

        Solution to this.



        1. First Check cache contains data or not.

        2. If Not create lock so following section only be executed by single thread.

        3. Now in that lock section again check for cache and if cache contains data then simply return but it does not contains then call external service.

        4. At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.

        5. Once that section get completed it store data in cache and so after if any queued or new request is there it choose data from cache.

        Note : It should something like this.



         public List<string> GetData()

        if(Cache[key] == null)

        lock(obj) // obj should be static

        if(Cache[key] == null)

        // Load data from service
        Cache[key] == data;



        return (List<string>)Cache[Key];






        share|improve this answer













        You are facing this issue because of following reason.



        1. You are using Cache and it will expire at some definite time.

        2. After Cache expire you call external web service method to collect the data. Now at this point of time it might happen that other request in queue get choose for execution.

        3. Once that another request is chosen for execution it also end up checking cache and it now data in cache then execute external service and so on for other request.

        Solution to this.



        1. First Check cache contains data or not.

        2. If Not create lock so following section only be executed by single thread.

        3. Now in that lock section again check for cache and if cache contains data then simply return but it does not contains then call external service.

        4. At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.

        5. Once that section get completed it store data in cache and so after if any queued or new request is there it choose data from cache.

        Note : It should something like this.



         public List<string> GetData()

        if(Cache[key] == null)

        lock(obj) // obj should be static

        if(Cache[key] == null)

        // Load data from service
        Cache[key] == data;



        return (List<string>)Cache[Key];







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 1:30









        dotnetstepdotnetstep

        11.4k43051




        11.4k43051



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291675%2fthreading-issue-in-asp-net-core%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Use pre created SQLite database for Android project in kotlin

            Darth Vader #20

            Ondo