Hello,
I am load testing my API and I got this error below.
Source ---
{0}BusinessService
StackTrace ---
{0} at BusinessService.GameServices.
d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Game.Controllers.GameController.d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.TaskHelpersExtensions.d__1`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.d__6.MoveNext()
TargetSite ---
{0}Void MoveNext()
Message ---
{0}A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
there is no such compilation warnings (cs4014) and I couldn't find any missing await in this code below;
- private async Task CallRazerService(RequestDto requestDto)
- {
- HttpResponseMessage response = null;
- using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
- {
-
- var config = new MapperConfiguration(cfg =>
- {
- cfg.CreateMap();
- cfg.CreateMap();
- cfg.CreateMap();
- cfg.CreateMap();
- });
- var iMapper = config.CreateMapper();
- var gameRequest = iMapper.Map(requestDto);
-
- gameRequest.referenceId = Guid.NewGuid().ToString();
-
- gameRequest = Utilities.CreateSignature(gameRequest, RequestType.Initiate);
-
-
-
- _unitOfWork.GameRepository.Insert(gameRequest);
-
- #region Call Razer initiate/confirm
-
-
- response = await Utilities.CallRazer(gameRequest, "purchaseinitiation");
-
-
- var htmlResponse = await response.Content.ReadAsStringAsync();
- var gameResponse = JsonConvert.DeserializeObject(htmlResponse);
-
-
- _unitOfWork.GameResponseRepository.Insert(gameResponse);
-
- if (gameResponse.initiationResultCode == "00")
- {
- gameRequest.validatedToken = gameResponse.validatedToken;
-
- var gameConfirmRequest = Utilities.CreateSignature(gameRequest, RequestType.Confirm);
-
-
- var gameConfirmRequests = iMapper.Map(gameConfirmRequest);
-
-
- _unitOfWork.GameConfirmRequestRepository.Insert(gameConfirmRequests);
-
-
- response = await Utilities.CallRazer(gameRequest, "purchaseconfirmation");
-
-
- htmlResponse = await response.Content.ReadAsStringAsync();
- var gameConfirmResponse = JsonConvert.DeserializeObject(htmlResponse);
-
-
- _unitOfWork.GameConfirmResponseRepository.Insert(gameConfirmResponse);
-
- }
-
- #endregion
-
- await _unitOfWork.SaveAsync();
- scope.Complete();
- }
-
- return response;
- }
By the way is it possible to make stack trace more handy, I mean it is hard to find where this error comes from. Here is my error logging code:
- public class UnhandledExceptionLogger : ExceptionLogger
- {
- public override void Log(ExceptionLoggerContext context)
- {
- var ex = context.Exception;
-
- string strLogText = "";
- strLogText += Environment.NewLine + "Source ---\n{0}" + ex.Source;
- strLogText += Environment.NewLine + "StackTrace ---\n{0}" + ex.StackTrace;
- strLogText += Environment.NewLine + "TargetSite ---\n{0}" + ex.TargetSite;
-
- if (ex.InnerException != null)
- {
- strLogText += Environment.NewLine + "Inner Exception is {0}" + ex.InnerException;
- }
- if (ex.Message != null)
- {
- strLogText += Environment.NewLine + "Message ---\n{0}" + ex.Message;
- }
-
- var requestedURi = (string)context.Request.RequestUri.AbsoluteUri;
- var requestMethod = context.Request.Method.ToString();
- var timeUtc = DateTime.Now;
-
- SqlErrorLogging sqlErrorLogging = new SqlErrorLogging();
- ApiError apiError = new ApiError()
- {
- Message = strLogText,
- RequestUri = requestedURi,
- RequestMethod = requestMethod,
- TimeUtc = DateTime.Now
- };
- sqlErrorLogging.InsertErrorLog(apiError);
- }
- }
Additional info: I got this error when I load test with 50 users and ramp-up period 5 seconds. If I load tesst with less users (10) I am not getting this error.
I wonder is this error due to JMeter load test settings? I think my ramp-up period is too short. What are your opinions?
The ramp-up period tells JMeter how long to take to "ramp-up" to the
full number of threads chosen. If 10 threads are used, and the ramp-up
period is 100 seconds, then JMeter will take 100 seconds to get all 10
threads up and running. Each thread will start
10 (100/10) seconds after the previous thread was begun. If there are
30 threads and a ramp-up period of 120 seconds, then each successive
thread will be delayed by 4 seconds.
Ramp-up needs to be long enough to avoid too large a work-load at the
start of a test, and short enough that the last threads start running
before the first ones finish (unless one wants that to happen).
Start with Ramp-up = number of threads and adjust up or down as needed.