Web API system out of memory exception - c#

I know there are a lot of questions regarding this issue. But I am unable to solve my problem.
API Flow
It accepts two parameters meter serial number and date time.
After the parameters are passed the API call is made
The API will search for the sent meter serial number in two databases.
After the record is fetched it should give the output.
Code
Below is my code
public HttpResponseMessage GetDetails(string msn, DateTime dt)
{
try
{
var prodDetails = mdcEntitites.tj_xhqd.Where(m => m.sjsj >= dt)
.Select(x => new { MSN = x.zdjh, PingDateTime = x.sjsj, PingValue = x.xhqd })
.ToList();
var mainDetails = kesc.tj_xhqd.Where(m => m.sjsj >= dt)
.Select(x => new { MSN = x.zdjh,PingDateTime= x.sjsj,PingValue = x.xhqd })
.ToList();
var res = prodDetails.Concat(mainDetails).ToList();
return Request.CreateResponse(HttpStatusCode.OK, new {details = res });
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
In above call, I am accepting a date time. When a meter is dispatched to field staff the date time is marked in the system, so the above date is that date time.
It will search all the records of that serial number after this date time.
Error
Using Postman when I try to run the API with current date time it gives me the following result
{
"details": [
{
"MSN": "002998002523",
"PingDateTime": "2018-06-21T08:38:12",
"PingValue": "26"
},
{
"MSN": "002998001286",
"PingDateTime": "2018-06-21T08:38:13",
"PingValue": "18"
},
.
.
.
.
.
]
}
But when I try to run the API with date time less than current date time it gives me below exception
Exception of type 'System.OutOfMemoryException' was thrown.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
System.IO.MemoryStream.set_Capacity(Int32 value) +89
System.IO.MemoryStream.EnsureCapacity(Int32 value) +90
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +326
Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +62
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9746340
System.Web.HttpResponse.FilterOutput() +104
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +58
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +48
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +71
How can I get rid of this issue?
Any help would be highly appreciated.

As dlxeon points out, the PageInspector might be the cause of your exception. However you have a potential problem anyway: you are not limiting the number of search results that you are returning, and that might be an issue in the future when your database grows. You could do something like that:
Add an optional page parameter to your API call, and add something like .Skip((page-1)*PageSize).Take(PageSize) to your database query, right after the .Where. This is assuming that pages start at 1 and you have a PageSize constant defined.1
Include paging information in your response as needed by the client, e.g:
{
"pageSize": 10,
"currentPage": 1,
"details: "[
...
]
}
1In your case it will be a bit more complex since you are doing two database queries, but you get the idea.

Related

Memory leak for nhibernate and fluent nhibernate

I have windows service that is basically reading messages from customer and we do process and sends them over HTTP/TCP/File etc. Service is written in C#, for database interaction I use NHibernate and TPL task.
For every batch of message service reads and inserts into SQL server database in separate TPL Task and same messages is then fetched from database in another TPL task we send them over HTTP/TCP/File after processing, and we also save this records into database using NHibernate ISession.
piece of code is below
public Func<ISession> GetSession { get; set; }
[Transaction]
public string SaveInMessage(ISession session, string message)
{
try
{
using (var session = GetSession()){
session.Transaction.Begin();
var inMessage = new InMessage();
var task = new Task(()=> InsertToDatabase(session, inMessage));
session.Transaction.Commit();
}
}
catch(Exception ex)
{
session.Transaction.Rollback();
}
}
public void InsertToDatabase(ISession session, InMessage inMessage){
session.SaveOrUpdate(inMessage);
}
[Transaction]
public bool SaveOutMessage()
{
try
{
using (var session = GetSession()){
session.Transaction.Begin();
var inMessage = session.Load<InMessage>();
var outMessage = new OutMessage();
var task = new Task(()=> ConvertMessage(outMessage, inMessage, session));
var task = new Task(()=> SendMessage(outMessage, session, outProtocol));
session.Transaction.Commit();
}
}
catch(Exception ex)
{
session.Transaction.Rollback();
}
}
public void ConvertMessage(OutMessage outMessage, ISession session, Http url)
{
conversion logic goes here;
}
public void SendMessage(OutMessage outMessage,ISession session,Protocol outProtocol)
{
Sending message logic goes here;
session.SaveOrUpdate(inMessage);
}
So, in above I have used Castle.Windsor for IoC and Transaction attribute used in these two methods are from same.
I am keep getting below AggregateException along with OutOfMemoryException within NHibernate and TPL.
System.AggregateException: One or more errors occurred. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.String.ConcatArray(String[] values, Int32 totalLength)
at System.String.Concat(Object[] args)
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at Service.ProcessMessage(Message message, ISession session) in C:\Project\Service\ProcessMessage.cs:line 247
at Service.ProcessMessage.<>c__DisplayClass22_0.<SendMessages>b__0(Task c) in C:\Project\Service\ProcessMessage.cs:line 74
at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait(CancellationToken cancellationToken)
at Service.ProcessMessage.SendMessages(CancellationToken cancelToken) in C:\Project\Service\ProcessMessage.cs:line 73
---> (Inner Exception #0) System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.String.ConcatArray(String[] values, Int32 totalLength)
at System.String.Concat(Object[] args)
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything)
at NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at Service.ProcessMessage.Process(Message message, ISession session) in C:\Project\Service\ProcessMessage.cs:line 247
at Service.ProcessMessage.<>c__DisplayClass22_0.<SendMessages>b__0(Task c) in C:\Project\Service\ProcessMessage.cs:line 74
at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
at System.Threading.Tasks.Task.Execute()<---
LogExtension.Event => LogExtension.Event => LogExtension.LogEvent
Above error is coming after 4-5 hours after windows service is started.
Any hint or help is appreciated.
.Net framework version I use is 4.5
NHibernate version is 4.0.4.4000
Castle.Windsor version is 3.3.0
FluentNhibernate version is 1.3.0.733
Castle.Facilities.NHibernate version is 0.7.1.23602
Castle.Facilities.AutoTx version is 3.2.207.2207
Castle.Core version is 3.3.3
You haven't posted your logic for GetSession(), but I get the impression you are re-using the same session for all of the messages. Sessions are supposed to be short lived. Keeping a single session open will result in the first level cache growing to the point where you get performance degradation and eventually run out of memory.

workitem.Save() storing multiple(duplicate) items into TFS

I am using below code to store workitem into TFS, but sometimes when TFS is unavailable/ or some exception, it is storing 4 items with same details into TFS. I am using below code.
private static void SaveWorkItemtoTFS(WorkItem wi, ref int retryCount)
{
try
{
retryCount++;
wi.Save();
}
catch (Exception ex)
{
if (retryCount <= 3)
{
Thread.Sleep(TimeSpan.FromSeconds(5));
wi.SyncToLatest();
SaveWorkItemtoTFS(wi, ref retryCount);
}
else
{
throw ex;
}
}
}
I just want to store unique items only. But it is storing 4 items with same details. Can you please help?
Exception is:
Technical information (for administrator):
The operation has timed out ---> System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.TeamFoundation.Client.Channels.TfsHttpWebRequest.SendRequestAndGetResponse(HttpWebRequest webRequest, WebException& webException)
--- End of inner exception stack trace ---
atTfsProj.BusinessLogic.SaveWorkItemtoTFS(WorkItem wi, Int32& retryCount)
atTfsProj.BusinessLogic.SaveWorkItemtoTFS(WorkItem wi, Int32& retryCount)
atTfsProj.BusinessLogic.SaveWorkItemtoTFS(WorkItem wi, Int32& retryCount)
atTfsProj.BusinessLogic.SaveWorkItemtoTFS(WorkItem wi, Int32& retryCount)
atTfsProj.BusinessLogic.AddNewCertificationTaskIntoTFS(RequestModel objRequestModel, String requestId, String clientReqId)`
this error only occurred once, unable to repro this as well.
According to the exception, the error occurs when get the response from TFS Server. When you create a workitem via Save() method, it will send the request to TFS Server first and then waiting for the response to check if the workitem is being created successfully. So in your question, the condition is that the create workitem request is sent successfully and workitem is created successfully but the code didn't get response from TFS Server which cause exception thrown and tried another three times.

Error in asp.net while testing web services

I have a web service that should pull about 80 records from SQL database. However recently it started giving me out of memory error.
When I debug it - it shows me the web service on the list, once I run it - get the error below.
webmethod:
[WebMethod(Description = "Getting Weekly Events by Facility, future events from sunday", CacheDuration = 600)]
public List<EventViewModel> GetWeeklyEvents(string facilityNumber, DateTime StDate)
{
var db = new DS_AIMDataContext();
var eventList = from evt in db.GetPublishedEventsFromSundayByFacility(facilityNumber, StDate)
select new EventViewModel
{
EventName = evt.ActName,
EventNameSpanish = evt.ActNameSp,
EventDescription = evt.ActDescription,
EventDescrSpanish = evt.ActDescrSp,
StDate = evt.EventStart.Value,
EndDate = evt.EventEnd.Value,
EventCategory = evt.CategoryName,
EventCatID = evt.ActCategID.Value,
EventType = evt.ActType,
EventLocation = evt.LocName,
EventLeader = evt.LeaderName,
EventCategorySp = evt.CategoryNameSp,
EventTypeSp = evt.ActTypeSp,
EventRecurrenceRule = evt.RecurrenceRule,
EventPhoto1 = evt.Photo1 == null ? null : evt.Photo1.ToArray(),
EventPhoto2 = evt.Photo2 == null ? null : evt.Photo2.ToArray(),
EventPhoto3 = evt.Photo3 == null ? null : evt.Photo3.ToArray()
};
return eventList.ToList();
}
The function itself:
public IEnumerable<tblEventsWithRecurr> GetPublishedEventsFromSundayByFacility(string facN, DateTime StDate)
{
var eventList = from evt in this.tblEventsWithRecurrs
orderby Convert.ToDateTime(evt.EventStart.ToString()).Day, Convert.ToDateTime(evt.EventStart.ToString()).Hour, Convert.ToDateTime(evt.EventStart.ToString()).Minute
where (evt.FacN == facN && evt.EventStatus == "Final" && evt.EventStart >= StDate && evt.EventStart <= StDate.AddDays(31))
select evt;
return eventList;
}
Error that I'm getting is below:
Server Error in '/' Application.
Exception of type 'System.OutOfMemoryException' was thrown.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
System.IO.MemoryStream.set_Capacity(Int32 value) +93
System.IO.MemoryStream.EnsureCapacity(Int32 value) +90
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +326
Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +61
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9641608
System.Web.HttpResponse.FilterOutput() +104
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +58
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
Couple of things:
First, how big are your Photo files - you have 3 photo's you're sending back. It would not be difficult to imagine a dozen very large photos on all of your results to max out whatever memory you have going on.
Secondly:
You may want to consider disposing of your datacontext.
Currently you have:
var db = new DS_AIMDataContext();
And this is never explicitly disposed, meaning the GC will eventually get to it, where you could instruct it to be disposed of the moment you are finished with it.
So try that line to:
using (DS_AIMDataContext db = new DS_AIMDataContext()){
// all of your eventList projection
// and your return statement
}
This will call Dispose as soon as your method completes and will hopefully free up memory.

NullReferenceException on 2nd Page_Load

At first I'd like to say: Yes I know that there are many Questions that are similar to mine, but not the same.
When I start one of my 12 sites on my developer-machine everything works wonderful, and also on the server 11 of them work without a problem.
When I start the 12th site it first works fine, but when it cause a postback (Button, DropDownList with AutoPostBack, etc... ) I get the following error:
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
Infoscreen.Anzeigeeinstellungen.Page_Load(Object sender, EventArgs e) in C:\Users\Krusty\Desktop\Schule\Diplomarbeit\Infoscreen\Infoscreen\Anzeigeeinstellungen.aspx.cs:97
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +24
System.Web.UI.Control.LoadRecursive() +70
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3047
the path (C:\Users\Krusty\Desktop\Schule\Diplomarbeit\Infoscreen\Infoscreen\Anzeigeeinstellungen.aspx.cs) is the one where the file was on my developer-machine.
but why??
I never hardcoded any path in my program, and even recreating the site didn't work.
What shall i do? Any tips/hints would be appreciated.
EDIT:
91 if (!Page.IsPostBack)
92 {
93 Response.Cookies["Infoscreen_Anzeigeeinstellungen_Ausgewählte_Abteilung"].Value = ausgewählte_Abteilung.ToString();
94 }
95 else
96 {
97 ausgewählte_Abteilung = Request.Cookies["Infoscreen_Anzeigeeinstellungen_Ausgewählte_Abteilung"].Value;
98 }
EDIT:
Yes, IIS is configured to use Cookies
EDIT:
SOLVED!
in VisualStudio2010 Server the char 'ä' works...
in IIS7 it doesn't...
so the cookie never gets set propperly and the get request hangs up
named the cookie "Infoscreen_Anzeigeeinstellungen_Ausgewaehlte_Abteilung" and it works fine now
can be closed
As you already found out your self but just for future reference:
In your code for handling the cookie the 'name' is allowed in c# (using a-umlaut) but as per RFC2616 the token for a cookie MUST contain a subset of US-ASCII chars.
if (!Page.IsPostBack)
{
Response.Cookies["Infoscreen_Anzeigeeinstellungen_Ausgewählte_Abteilung"].Value = ausgewählte_Abteilung.ToString();
}
else
{
ausgewählte_Abteilung = Request.Cookies["Infoscreen_Anzeigeeinstellungen_Ausgewählte_Abteilung"].Value;
}
So a way to have a safe Cookies key in case your cookiekey is generated based on form/controlnames could be:
static string TokenRFC2616(string key)
{
const string separators = "()|<>#,;:\\\"/[]?={} ";
var chars = from ch in key.Normalize(NormalizationForm.FormD)
where CharUnicodeInfo.GetUnicodeCategory(ch)
!= UnicodeCategory.NonSpacingMark &&
separators.IndexOf(ch)==-1
select ch;
return String.Concat(chars);
}
string cookiekey = TokenRFC2616(
"Infoscreen_Anzeigeeinstellungen_Ausgewählte_Abteilung");
if (!Page.IsPostBack)
{
Response.Cookies[cookieKey].Value = ausgewählte_Abteilung.ToString();
}
else
{
ausgewählte_Abteilung = Request.Cookies[cookieKey].Value;
}
(in the above sample the cookie name will be Infoscreen_Anzeigeeinstellungen_Ausgewahlte_Abteilung
)

jqGrid weird exception upon calling databind

I have been using the latest MVC dll from Trirand and I am using the JqGrid.Databind() function to get data from the controller. Here is the code that I have written:
var listToBind = gridDataTable.Cast<IDictionary>().ToDataSource();
gridModel.ResourcePlanningGrid.DataSource = null;
JsonResult returnObject;
try
{
returnObject = gridModel.ResourcePlanningGrid.DataBind(listToBind.AsQueryable());
}
catch(Exception ex)
{
//Unknown Exception: delete the current session that holds the grid and
//restart the whole page
this.Session["ResourcePlanningGrid"] = null;
return FilterData();
}
Intermittently it throws an exception on the .DataBind() call that says that it parses a string that is not a valid Boolean. Has anyone encountered this before? Is there an existing fix for this? or should I find another way to pass values from a list to bind?
Here is the the exception stack trace.
at System.Boolean.Parse(String value)
at System.Convert.ToBoolean(String value)
at Trirand.Web.Mvc.JQGrid.get_AjaxCallBackMode()
at Trirand.Web.Mvc.JQGrid.DataBind()
at Trirand.Web.Mvc.JQGrid.DataBind(Object dataSource)
at Cormant.OrangeReports.Web.Controllers.ResourcePlanningController.FilterData(Nullable`1 customerID, Nullable`1 projectID, Nullable`1 startDate, Nullable`1 endDate, String employeeID) in e:\Projects\OrangeReports\Cormant.OrangeReports.Web\Controllers\ResourcePlanningController.cs:line 175
Thanks in Advance

Categories

Resources