Threading issue in ASP.NET Core
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
add a comment |
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
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
add a comment |
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
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
c# async-await
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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
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 generalasync
might be a default choice, my point is that "always" is a strong word here.
– zerkms
Nov 14 '18 at 1:05
add a comment |
You are facing this issue because of following reason.
- You are using Cache and it will expire at some definite time.
- 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.
- 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.
- First Check cache contains data or not.
- If Not create lock so following section only be executed by single thread.
- 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.
- At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.
- 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];
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
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 generalasync
might be a default choice, my point is that "always" is a strong word here.
– zerkms
Nov 14 '18 at 1:05
add a comment |
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
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 generalasync
might be a default choice, my point is that "always" is a strong word here.
– zerkms
Nov 14 '18 at 1:05
add a comment |
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
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
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 generalasync
might be a default choice, my point is that "always" is a strong word here.
– zerkms
Nov 14 '18 at 1:05
add a comment |
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 generalasync
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
add a comment |
You are facing this issue because of following reason.
- You are using Cache and it will expire at some definite time.
- 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.
- 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.
- First Check cache contains data or not.
- If Not create lock so following section only be executed by single thread.
- 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.
- At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.
- 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];
add a comment |
You are facing this issue because of following reason.
- You are using Cache and it will expire at some definite time.
- 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.
- 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.
- First Check cache contains data or not.
- If Not create lock so following section only be executed by single thread.
- 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.
- At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.
- 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];
add a comment |
You are facing this issue because of following reason.
- You are using Cache and it will expire at some definite time.
- 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.
- 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.
- First Check cache contains data or not.
- If Not create lock so following section only be executed by single thread.
- 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.
- At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.
- 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];
You are facing this issue because of following reason.
- You are using Cache and it will expire at some definite time.
- 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.
- 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.
- First Check cache contains data or not.
- If Not create lock so following section only be executed by single thread.
- 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.
- At this point of time if another thread get selected for execution then it has to wait for execlsive section to complete its works.
- 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];
answered Nov 14 '18 at 1:30
dotnetstepdotnetstep
11.4k43051
11.4k43051
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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