C#: Line number on stacktrace points to line with a } - c#

Suggestions on resolving this? I keep coming up with "missing" line numbers when consulting the google machine and that isn't the issue we are having. We have a line number but it doesn't point to anything but a closing brace.
Could this be because it is a timeout? It seems strange that it consistently gives up at the very end of the method, and the same method no less. The time outs are not necessarily frequent and the application (win forms calling asmx web service) does timeout in other places at times.
Edit: Code and Stack trace.
public DataSet GetData(...)
{
// About 18 try/catch blocks loading tables in dataset, all similar to below
try
{
// Create Table Adapter
// Fill Table
}
catch (Exception ex)
{
LogError(ex, System.Reflection.MethodBase.GetCurrentMethod(), null);
throw ex;
}
} //Line 479
System.Web.Services.Protocols.SoapException:
System.Web.Services.Protocols.SoapException:
Server was unable to process request.
---> System.Data.SqlClient.SqlException:
Timeout expired. The timeout period
elapsed prior to completion of the
operation or the server is not
responding. at
MonitoringDataService.AddAllData(DataSet
Data, DateTime LastSync, String
PrevAreas, String NewAreas, DateTime
PrevStartDate, DateTime PrevEndDate,
DateTime NewStartDate, DateTime
NewEndDate, Int32 CurrentUser, Boolean
IsInGroup) in
MonitoringDataService.cs:line 479
Worth noting that this is the inner exception.

Likely causes:
The code that is running is different from the source you are debugging from. This is the most likely cause.
Line could be the line after a throw new exception(...)

More than likely it's not really erroring on the end brace, but the line before it.

Related

Catch time out exception

I am trying to catch if timeout error occurs in Oracle. After googling a lot i did not find any specific fix for it. I have done below
try{}
catch (OracleException ex)
{
if (ex.Number == 01013)
CatchException(ex);
}
But i am not sure if timeout exception number is 01013.
Yes the code is 01013. Please refer the Oracle docs:
Default is 0 seconds, which enforces no time limit.
When the specified timeout value expires before a command execution
finishes, the command attempts to cancel. If cancellation is
successful, an exception is thrown with the message of ORA-01013: user
requested cancel of current operation. If the command executed in time
without any errors, no exceptions are thrown.
In a situation where multiple OracleCommand objects use the same
connection, the timeout expiration on one of the OracleCommand objects
may terminate any of the executions on the single connection. To make
the timeout expiration of a OracleCommand cancel only its own command
execution, simply use one OracleCommand for each connection if that
OracleCommand sets the CommandTimeout property to a value greater than
0.
Please note that there are possibly two other error codes which will throw when the .CommandTimeout is exceeded. Those are ORA-00936 and ORA-00604. Found in the docs.
When the specified timeout value expires before a command execution finishes, the command attempts to cancel. If cancellation is successful, an exception is thrown with the message of ORA-01013: user requested cancel of current operation. Other possible exceptions thrown after a command timeout expiration occurs include ORA-00936 and ORA-00604. If the command executed in time without any errors, no exceptions are thrown.
So your code should be:
try
{
// Data Access
}
catch (OracleException ex)
{
if (ex.Number == 01013 || ex.Number == 00936 || ex.Number == 00604)
CatchException(ex);
}

C# Multithreading Console runtime error

I have a Console app that uses a parallel.foreach producing a number of working threads that performs some tasks such as
reading OS data through SNMP from a number of servers in our intranet and
writes these values to a SQL server DB.
When I ran the code within Visual Studio 2010 in either debug- or release mode the program executes without exceptions. When I deploy the program and run it outside VS I get an exception (.NET Runtime Exceptiopn).
Stack Trace:
Application: ServerMonitorSNMP.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AggregateException Stack: at System.Threading.Tasks.Parallel.ForWorker[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](Int32, Int32, System.Threading.Tasks.ParallelOptions, System.Action`1,
...
at ServerMonitoringSNMP.Program.Main(System.String[])
The AggregateException details are:
System.UnhandledExceptionEventArgs
System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
...
(Inner Exception #0) System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
...
(Inner Exception #1) System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
...
(Inner Exception #2) System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
...
System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at ServerMonitoringSNMP.Program.GetStorageValue(Dictionary`2 StorageQuery, Int32 diskOidIndex) in \Program.cs:line 896
This is an unhandled aggregate exception. You will need to catch this type of error, loop through its exceptions and log each one to figure out what is going on.
You are probably not breaking on these types of exceptions in your debug routine.
Turn on Break on All Exceptions (Debug, Exceptions) or (CTRL + ALT + E) and rerun the program.
This will show you the original exception when it was thrown in the first place.
Catch code:
catch (AggregateException e)
{
foreach (var ex in e.InnerExceptions)
{
//log here
}
}
The attached exception is too abstract. The best approach would be handle the TPL exception and log. Things shall be much clearer when you do so. Then you can updated the post with proper exception.
Eg:
try
{
YourSNMPTrapSenderMethod();
}
catch (AggregateException ae)
{
// This is where you can choose which exceptions to handle.
foreach (var ex in ae.InnerExceptions)
{
// log your exception. may be in temp directory
}
}
Or
try
{
YourSNMPTrapSenderMethod();
}
catch (AggregateException ex)
{
ex.Handle((x) =>
{
Log.Write(x);
return true;
});
}
static void YourSNMPTrapSenderMethod()
{
var exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(data, d =>
{
try
{
//do your operations
}
catch (Exception e) { exceptions.Enqueue(e); }
});
if (exceptions.Count > 0) throw new AggregateException(exceptions);
}

TransactionScope TransactionAborted Exception - transaction not rolled back. Should it be?

(SQL SERVER 2008)
If a Transaction Timeout error occurs within a TransactionScope (.Complete()) would you expect the transaction to be rolled back?
Update:
The error is actually being thrown in the closing curly brace (i.e. .Dispose()), not .Complete(). Full error is:
The transaction has aborted. System.Transactions.TransactionAbortedException TransactionAbortedException System.Transactions.TransactionAbortedException: The transaction has aborted. ---> System.TimeoutException: Transaction Timeout
--- End of inner exception stack trace ---
at System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
As far as I can tell the transaction is not rolled back and the tables remained locked until I issued a KILL against the SPID/session_id.
I used DBCC OPENTRAN to get the oldest transaction and then KILL it.
I have tried KILL WITH STATUS but get a message that no status is available as nothing is being rolled back. Status of the SPID/session_id in sys.dm_exec_sessions is 'sleeping'. Code snippet:
try
{
using (var transaction = new TransactionScope())
{
LOTS OF WORK CARRIED OUT WITH LINQ ENTITIES/SubmitChanges() etc.
transaction.Complete(); //Transaction timeout
}
return result;
}
catch (Exception ex)
{
logger.ErrorException(ex.Message, ex);
result.Fail(ex.Message);
return result;
}
UPDATE:
Problem is not entirely solved, but further information should anyone else have this problem.
I am using LINQ to SQL and within the transaction scope I call context.SubmitChanges(). I am carrying out a lot of inserts. SQL Server profiler indicates that a separate INSERT statement is issued for each insert.
In development, if I sleep the thread for 60 seconds (default TransactionScope timeout is 60 seconds) BEFORE calling SubmitChanges() then I get a different error when calling TransactionScope.Complete() (The operation is not valid for the state of the transaction.).
If I sleep for 60 seconds AFTER .SubmitChages() and just before .Complete() then I get
'The transaction has aborted - System.TimeoutException: Transaction Timeout'
NOTE however that on my dev machine no open transactions are found when using DBCC opentran - which is what you would expect as you would expect the transaction to rollback.
If I then add the code at the bottom of this question (sorry couldn't get the website to insert it here) to my config file which increases the TransactionScope timeout to 2 minutes, things start working again (research indicates that if this doesn't work there could be a setting in machine.config that is lower than this that is taking precedence).
Whilst this will stop the transaction aborting, due to the nature of the updates, it does mean that locks on a core business table could be up to 2 minutes so other select commands using the default SqlCommand timeout of 30 seconds will timeout. Not ideal, but better than an open transaction sitting there and totally holding up the application.
A few days ago we had a disastrous release that meant we ran out of diskspace mid upgrade (!) so we did end up using the shrink database functionality which apparently can cause performance problems after you have used it.
I feel a rebuild of the database and a rethink of some business functionality coming on...
I'm thinking that the TransactionAbortedException is actually a timeout. If so you should find that the InnerException of the TransactionAbortedException is a timeout.
You should be able to get rid of it by making sure that the timeout of the transactionscope is longer than the command timeout.
Try changing the transaction scope to something like this:
new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(60))
And also set an explicit timeout on your context. Should be something like:
myContext.CommandTimeout = 30; //This is seconds
I resolve this problem modifying the "physical file" machine.config.
1. You have to localize the file:
32 Bits: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machie.config
64 Bits: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config
2. You have to add the following code:
<system.transactions>
<defaultSettings timeout="00:59:00" />
</system.transactions>

SqlException not being caught

I have an ASP.Net application with the following code:
try
{
sql = new SqlProc("prcCustomerAgeSelect",
SqlProc.InParam("#DateFrom", SqlDbType.DateTime, 8, _OrderDateFrom),
SqlProc.InParam("#DateTo", SqlDbType.DateTime, 8, _OrderDateTo),
sql.Command.CommandTimeout = 1;
dt = sql.ExecuteTable();
}
catch (SqlException ex)
{
Filter.ErrorMessage = "Please narrow your search criteria.";
}
Note the line:
sql.Command.CommandTimeout = 1;
Which causes a SqlException to be thrown (for testing).
I would have thought that the catch block would catch this exception, but it doesn't. Instead, I get:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.]
Why doesn't it catch it?? Am I using the wrong type? What am I missing here?
Thanks in advance!!
-Ev
It sounds like what you're seeing isn't a SqlException.
It's possible that SqlProc is itself catching SqlExceptions, extracting some information from them, then throwing new exceptions of a different type (embedding some of the original info in the new exception's message).
It looks like it may be a connection timeout, rather than a command timeout.
I would check to make sure that you can connect and run the query with a more sensible timeout value just to verify this.

Accepted way to prevent "The remote host closed the connection" exception

I'm constantly getting the following exception which is caused by a user initiating a download and it consequently failing (or being cancelled):
Error Message : The remote host closed
the connection. The error code is
0x80072746. Stack Trace : at
System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.FlushCore(Byte[]
status, Byte[] header, Int32
keepConnected, Int32 totalBodySize,
Int32 numBodyFragments, IntPtr[]
bodyFragments, Int32[]
bodyFragmentLengths, Int32
doneWithSession, Int32 finalStatus,
Boolean& async) at
System.Web.Hosting.ISAPIWorkerRequest.FlushCachedResponse(Boolean
isFinal) at
System.Web.Hosting.ISAPIWorkerRequest.FlushResponse(Boolean
finalFlush) at
I've searched all over the internet, and found an interesting article, however there doesn't seem to be a definitive answer as the best way to prevent this filling up the logs.
The user sees no error and there's no actual problem in the app as it occurs only (to my understanding) in situations out of its control (user cancelling download or loss of connection) but there has to be a way to prevent such an exception being reported.
I hate to say it but I'm tempted to check for this exception and empty catch block its ass away - but this makes me feel like a dirty programmer.
So - what is the accepted method of preventing this exception filling up my mailbox?
The error occurs when you try to send a response to the client but they have disconnected. You can verify this by setting a breakpoint on the Response.Redirect or wherever you are sending data to the client, wait for Visual Studio to hit the breakpoint, then cancel the request in IE (using the x in the location bar). This should cause the error to occur.
To capture the error you can use the following:
try
{
Response.Redirect("~/SomePage.aspx");
Response.End();
}
catch (System.Threading.ThreadAbortException)
{
// Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex)
{
if (ex.ErrorCode == unchecked((int)0x80070057)) //Error Code = -2147024809
{
// Do nothing. This will happen if browser closes connection.
}
else
{
throw ex;
}
}
Or in C# 6 you can use Exception filters to prevent having to re throw the error:
try
{
Response.Redirect("~/SomePage.aspx");
Response.End();
}
catch (System.Threading.ThreadAbortException)
{
// Do nothing. This will happen normally after the redirect.
}
catch (System.Web.HttpException ex) when (ex.ErrorCode == unchecked((int)0x80070057))
{
// Do nothing. This will happen if browser closes connection.
}
Which is a better debugging experience since it will stop on the statement throwing the exception with the current state and all local variables preserved instead of on the throw inside the catch block.
You cannot prevent a remote Host to close anything.
And in some protocols this is the normal (or at least accepted) way to say goodbye.
So you will have to handle this specific exception.
From a practical perspective, there is nothing wrong with cancelling a download by virtue of a dead computer or a killed web session, therefore catching remote host closed exceptions is perfectly acceptable.

Categories

Resources