workitem.Save() storing multiple(duplicate) items into TFS - c#

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.

Related

Azure Service Bus: AMQP object is closing. Operation 'attach' cannot be performed

I'm using Azure Service Bus Topics with the AMQP protocol in the West Europe datacenter.
This is a schematic way of how the solution implented works:
private Microsoft.Azure.ServiceBus.SubscriptionClient CreateClient() {
string serviceBusConnectionString;
strin serviceBusTopicName;
string subscriptionName;
var subscriptionClient = new Microsoft.Azure.ServiceBus.SubscriptionClient(serviceBusConnectionString, serviceBusTopicName, subscriptionName) {
PrefetchCount = 0
};
return subscriptionClient;
}
public async Task<ISubscriptionClient> CreateSubscriptionClientAsync() {
//Some logic on the subscriptionClient, caching, creating a new one if it doesn't exists, etc.
return CreateClient()
}
private async Task CallbackAsync(Message msg, CancellationToken cancellationToken) {
//Do stuff with the Message
//when you're done Completethe message
}
public async Task<string> OpenAsync(CancellationToken cancellationToken) {
subscriptionClient = await CreateSubscriptionClientAsync().ConfigureAwait(false);
var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandlerAsync) {
AutoComplete = false,
MaxAutoRenewDuration = TimeSpan.FromHours(8)
};
subscriptionClient.RegisterMessageHandler(CallbackAsync, messageHandlerOptions);
return string.Empty;
}
But last night I had couple of thousand exception like this one:
Exception: "System.InvalidOperationException: The AMQP object g2b-sessionXXXXXXXX is closing. Operation 'attach' cannot be performed.
at Microsoft.Azure.ServiceBus.Core.MessageReceiver.<OnReceiveAsync>d__86.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 Microsoft.Azure.ServiceBus.Core.MessageReceiver.<>c__DisplayClass64_0.<<ReceiveAsync>b__0>d.MoveNext()
I'm using the Microsoft.Azure.ServiceBus v3.1.0.0,
On line I didn't find anything useful about this "Operation 'attach' cannot be performed".
On the message bus exception list page I didn't find any information about this specific problem. And in the status history site there is no reference about any outage involving Service Bus.
Did anyone experience this problem before?
What is causing the exception?
Do I need to implement any retry logic? How?
Any help is apreciated, thanks.

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.

Web API system out of memory exception

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.

OutOfMemory exception on Exception.ToString()

Below is some logging output from a .NET application.
Error in MainFunction.
Message: Exception of type 'System.OutOfMemoryException' was thrown.
InnerException:
StackTrace: at System.Text.StringBuilder.ToString()
at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Exception.GetStackTrace(Boolean needFileInfo)
at System.Exception.ToString(Boolean needFileLineInfo)
at System.Exception.ToString()
[the rest of the trace is removed]
Which corresponds to the following line of application code. The following is in a catch block, and returns the string to the method that actually throws:
private void MainFunction()
{
...
try
{
string doc = CreateXMLDocument(); // <- Out of Memory throws here
}
catch (Exception ex)
{
CoreLogging("Error in MainFunction.", ex);
}
}
private string CreateXMLDocument()
{
try
{
//Some basic and well constrained XML document creation:
...
}
catch (Exception ex)
{
return "Exception message: " + ex.ToString(); // <- This is the last line of the trace
}
}
What should I make of this? Clearly Exception.Message should be used instead of Exception.ToString(), but I'd still like to understand this. Does
at System.Text.StringBuilder.ToString()
at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
mean that the stack trace of the exception in CreateXMLDocument was so mammoth caused OutOfMemory? I'm curious to see how that would occur as there's definitely no circular calls in CreateXMLDocument, which is the only thing I can think of that could cause an enormous stack trace.
Has anyone else encountered a similar situation?
I little bit of guessing:
1) CLR rises a OutOfMemoryException. 2) You catch this exception and call .ToString on it
3) ToString() tries to allocate memory to the stack trace but... there is no memory and another OutOfMemoryException is rised.
In the comments you said that the XML documents have a few hundreds of kbytes, this could be a/the problem if your server run on 32bits, because of the fragmentation of the LOH.

throw new Exception while keeping stack trace and inner exception information

I have a FileSystemWatch program that I'm working on and if there's an error copying a file, I want to be able to know which file it failed on. At the same time, I'd like to be able to retain the stack trace, as well as the inner exception information.
if (!found)
{
try
{
File.Copy(file, Path.Combine(watchDirectory, filename));
}
catch (Exception ex)
{
WriteToLog(new Exception(
String.Format("An error occurred syncing the Vault location with the watch location. Error copying the file {0}. Error = {1}", file, ex.Message), ex.InnerException));
}
}
So, the exception that gets passed, I still want to have the stacktrace info that, the inner exception info, but I want the "message" to be my custom message that contains which file it failed on, while also displaying the "real" message that was thrown by the original exception.
I changed the new exception to accept ex as the inner exception instead of ex.InnerException. If you call ToString() on your new exception instance, it will include the full stack trace and all inner exceptions.
try
{
// ...
}
catch (Exception ex)
{
string message = String.Format("An error occurred syncing the Vault location with the watch location. Error copying the file {0}.", file);
Exception myException = new Exception(message, ex);
string exceptionString = myException.ToString(); // full stack trace
//TODO: write exceptionString to log.
throw myException;
}

Categories

Resources