Cenk

Cenk

  • NA
  • 92
  • 13.2k

A second operation started on this context before a previous

Jul 18 2019 12:46 AM
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;
 
  1. private async Task CallRazerService(RequestDto requestDto)  
  2.         {  
  3.             HttpResponseMessage response = null;  
  4.             using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))  
  5.             {  
  6.                 //Transform DTO into GameRequest for calling Razer Initiate  
  7.                 var config = new MapperConfiguration(cfg =>  
  8.                 {  
  9.                     cfg.CreateMap();  
  10.                     cfg.CreateMap();  
  11.                     cfg.CreateMap();  
  12.                     cfg.CreateMap();  
  13.                 });  
  14.                 var iMapper = config.CreateMapper();  
  15.                 var gameRequest = iMapper.Map(requestDto);  
  16.                 //Unique reference ID  
  17.                 gameRequest.referenceId = Guid.NewGuid().ToString();  
  18.                 //Create signature  
  19.                 gameRequest = Utilities.CreateSignature(gameRequest, RequestType.Initiate);  
  20.   
  21.   
  22.                 //Add initiation request into database  
  23.                 _unitOfWork.GameRepository.Insert(gameRequest);  
  24.  
  25.                 #region Call Razer initiate/confirm  
  26.   
  27.                 //Call Razer for initiation  
  28.                 response = await Utilities.CallRazer(gameRequest, "purchaseinitiation");  
  29.   
  30.                 //Read response  
  31.                 var htmlResponse = await response.Content.ReadAsStringAsync();  
  32.                 var gameResponse = JsonConvert.DeserializeObject(htmlResponse);  
  33.   
  34.                 //Adding initiation response into database  
  35.                 _unitOfWork.GameResponseRepository.Insert(gameResponse);  
  36.   
  37.                 if (gameResponse.initiationResultCode == "00")  
  38.                 {  
  39.                     gameRequest.validatedToken = gameResponse.validatedToken;  
  40.                     //Create signature  
  41.                     var gameConfirmRequest = Utilities.CreateSignature(gameRequest, RequestType.Confirm);  
  42.   
  43.                     //Transform DTO into GameRequest for calling Razer Initiate  
  44.                     var gameConfirmRequests = iMapper.Map(gameConfirmRequest);  
  45.   
  46.                     //Add confirm request into database  
  47.                     _unitOfWork.GameConfirmRequestRepository.Insert(gameConfirmRequests);  
  48.   
  49.                     //Call Razer for confirm  
  50.                     response = await Utilities.CallRazer(gameRequest, "purchaseconfirmation");  
  51.   
  52.                     //Read response  
  53.                     htmlResponse = await response.Content.ReadAsStringAsync();  
  54.                     var gameConfirmResponse = JsonConvert.DeserializeObject(htmlResponse);  
  55.   
  56.                     //Add confirm response into database  
  57.                     _unitOfWork.GameConfirmResponseRepository.Insert(gameConfirmResponse);  
  58.   
  59.                 }  
  60.  
  61.                 #endregion  
  62.   
  63.                 await _unitOfWork.SaveAsync();  
  64.                 scope.Complete();  
  65.             }  
  66.   
  67.             return response;  
  68.         } 
 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:
 
  1. public class UnhandledExceptionLogger : ExceptionLogger  
  2.     {  
  3.         public override void Log(ExceptionLoggerContext context)  
  4.         {  
  5.             var ex = context.Exception;  
  6.   
  7.             string strLogText = "";  
  8.             strLogText += Environment.NewLine + "Source ---\n{0}" + ex.Source;  
  9.             strLogText += Environment.NewLine + "StackTrace ---\n{0}" + ex.StackTrace;  
  10.             strLogText += Environment.NewLine + "TargetSite ---\n{0}" + ex.TargetSite;  
  11.   
  12.             if (ex.InnerException != null)  
  13.             {  
  14.                 strLogText += Environment.NewLine + "Inner Exception is {0}" + ex.InnerException;  
  15.             }  
  16.             if (ex.Message != null)  
  17.             {  
  18.                 strLogText += Environment.NewLine + "Message ---\n{0}" + ex.Message;  
  19.             }  
  20.   
  21.             var requestedURi = (string)context.Request.RequestUri.AbsoluteUri;  
  22.             var requestMethod = context.Request.Method.ToString();  
  23.             var timeUtc = DateTime.Now;  
  24.   
  25.             SqlErrorLogging sqlErrorLogging = new SqlErrorLogging();  
  26.             ApiError apiError = new ApiError()  
  27.             {  
  28.                 Message = strLogText,  
  29.                 RequestUri = requestedURi,  
  30.                 RequestMethod = requestMethod,  
  31.                 TimeUtc = DateTime.Now  
  32.             };  
  33.             sqlErrorLogging.InsertErrorLog(apiError);  
  34.         }  
  35.     } 
 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.

 

Answers (4)