var counter = new PerformanceCounter{};
counter.CategoryName = "Process";
counter.CounterName = "% Processor Time";
counter.InstanceName = someProcessName;
if ( PerformanceCounterCategory.InstanceExists( someProcessName, "Process" ) )
{
// For any reason the process terminates EXACTLY at this point
counter.NextValue();
// we'll get a InvalidOperationException exception here
}
Is there any possibility to use PerformanceCounter.NextValue method in a safe manner. Just for the record, I know It's very unlikely to have this type of scenario.
Look at MSDN - InvalidOperationException is throwed when The instance is not correctly associated with a performance counter.
PerformanceCounter.NextValue Method
Try to initialize your counter with RawValue property:
// Initialize the counter.
counter.RawValue = Stopwatch.GetTimestamp();
If this won't help - check if category and counter names are valid
use try-catch like this:
var counter = new PerformanceCounter{};
counter.CategoryName = "Process";
counter.CounterName = "% Processor Time";
counter.InstanceName = someProcessName;
try
{
if ( PerformanceCounterCategory.InstanceExists( someProcessName, "Process" ) )
{
// For any reason the process terminates EXACTLY at this point
counter.NextValue();
}
}
catch(InvalidOperationException error)
{
//deal with exception
}
Related
This question already has answers here:
Testing for Dictionary KeyNotFoundException
(4 answers)
Closed 5 years ago.
I'm building a project where the config file will be load as a dictionary. To prevent from invalid config, I simply added an try catch frame. But I noticed that when exceptions throw, there will be a dramatic performance dropping. So I made a test:
var temp = new Dictionary<string, string> {["hello"] = "world"};
var tempj = new JObject() {["hello"]="world"};
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100; i++)
{
try
{
var value = temp["error"];
}
catch
{
// ignored
}
}
sw.Stop();
Console.WriteLine("Time cost on Exception:"+sw.ElapsedMilliseconds +"ms");
sw.Restart();
for (int i = 0; i < 100; i++)
{
var value = tempj["error"]; //equivalent to value=null
}
Console.WriteLine("Time cost without Exception:" + sw.ElapsedMilliseconds + "ms");
Console.ReadLine();
And the result is:
Time cost on Exception:1789ms
Time cost without Exception:0ms
The JObject here is taken from Newtownsoft.Json, which does not throw an exception when no key is found ,as opposed to Dictionary.
So my question is:
Does exception throwing really slow down the program that much?
How do I guarantee the performance when multiple exceptions may occur?
Anyway work around if I really want to use Dictionary in this case?(shut down the KeyNotFoundException?)
Thank you!
Use Dictionary.TryGetValue to avoid exceptions in your example code at all. The most expensive part is the try .. catch.
If you cannot get away from exceptions then you should use a different pattern to perform actions inside a loop.
Instead of
for ( i = 0; i < 100; i++ )
try
{
DoSomethingThatMaybeThrowException();
}
catch (Exception)
{
// igrnore or handle
}
which will set up the try .. catch for every step whether an exception has raised or not, use
int i = 0;
while ( i < 100 )
try
{
while( i < 100 )
{
DoSomethingThatMaybeThrowException();
i++;
}
}
catch ( Exception )
{
// ignore or handle
i++;
}
which will only set up a new try .. catch when an exception was thrown.
BTW
I cannot reproduce that massive slowdown of your code as you describe. .net fiddle
I'm new to c# working with a windows service which has a timer but the autoreset is set to false so it supposed to run an infinite loop Querying to a Sql database. If the SQL returns records the process runs fine, but when no records are found the service throws an exception after 10 - 12 minutes, System.StackOverflowException was unhandled which is not clear (to me). Not sure how to better capture the issue or how to correct. Any assistance would be apprecieated.
`private static bool LoadRequests()
{
// check for requests will return combined Header/Detail record
bool RequestsLoaded = false;
string XMLURL = "";
string currentWorkingDirectory = "";
string text = "";
int rowcounter = 0;
try
{
//Summary List will be a subset of requested items, by ID#
var SummaryInfoList = new List<SummaryInfo>();
ReqHdrPlusDtlList myReqHdrPlusDetailList = new ReqHdrPlusDtlList();
List<ReqHdrPlusDtl> myReqHdrPlusDetailList = myReqHdrPlusDetailList.GetReqHdrPlusDtlList();
if (myReqHdrPlusDetailList != null && myReqHdrPlusDetailList.Count > 0)
{
// set check for last record
ReqHdrPlusDtl last = myReqHdrPlusDetailList.Last();
// scroll through each record in Request List
foreach (ReqHdrPlusDtl detailrec in myReqHdrPlusDetailList)
{
/// process id records ...
/// ...
} // exit for/each
}
else
{
//no records in list sleep for half a second before proceeding
Thread.Sleep(500);
text = "Done sleeping...";
WriteToAppLog(text);
}
//As soon as one request is fully processed, get the next pending record.
LoadRequests();
} // ends try
catch (Exception e)
{
WriteErrorMessageToAppLog(e);
RequestsLoaded = false;
}
return RequestsLoaded;
}`
When you look for the exception in the docs it states the following.
The exception that is thrown when the execution stack overflows because it contains too many nested method calls.
This exception often happens when you have an infinite loop, like in your code.
You are working with recursion (Recursion is an important programming technique that causes a function to call itself, source).
Because you keep calling your own function over and over again, you keep building up the stack, until it overflows.
You should rewrite the function so that it will actually end.
I suggest using a DispatcherTimer to call your function every 500ms, instead of Thread.Sleep() because Thread.Sleep() also blocks any execution of code on that thread.
private DispatcherTimer _dispatcherTimer;
private void SetUpTimer(){
_dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
_dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
_dispatcherTimer.Interval = TimeSpan.FromMilliseconds(500);
_dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
LoadRequests();
}
Note: I didn't test the code, and I haven't written c# in a while, though it should help you get there
You are using a recursive call which is causing the stack overflow problem. Get rid of the recursive call to correct. Possibly make a control loop as follows:
bool success = true;
while(success)
{
try
{
LoadRequests();
Thread.Sleep(500);
}
catch (exception ex)
{
//Log Error ex.Message;
success = false;
}
}
Once you eliminate calling the function inside of itself, the stack overflow problem should be resolved.
Edit
One other comment, is the recursion is never-ending (no control statement to block execution) which is a big no-no. If you have to use recursion then there must be a way to exit the method (a stop condition). All that being said, almost every recursive problem can be solved iteratively and it can be very beneficial to do so, as it consumes significantly less system resources. The above listed code would be an iterative solution.
My code:
public void CPUStats()
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time",
"_Total");
var ramCounter = new PerformanceCounter("Memory", "Available MBytes");
ramCounter.NextValue();
cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000);
string cpusage = cpuCounter.NextValue().ToString();
string ramusage = ramCounter.NextValue().ToString();
//Occurs here v
try
{
//exception thrown here v
cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = "CPU: " +
cpusage.Remove(cpusage.IndexOf('.')) + "%"));
}
catch(ArgumentOutOfRangeException)
{
cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = "CPU: " +
cpusage + "%"));
}
ramLabel.Invoke((MethodInvoker)(() => ramLabel.Text = "Free RAM: " +
ramusage + "mb"));
}
At times my application will stop at the cpuLabel invoke and throw an "ArgumentOutOfRangeException" when it was handled and fixed in my code. I tried increasing the timer that activates the thread that activates CPUStats(), but to no avail.
Why would this happen?
Update:
Sorry, I should read your code more carefully. Your try-catch wrapped the delegate invocation which may not in the current context of thread. I think what you want to do should be:
public void CPUStats() {
var cpuCounter= ..
...
MethodInvoker m=() => {
try {
cpuLabel.Text="CPU: "+cpusage.Remove(cpusage.IndexOf('.'))+"%";
}
catch(ArgumentOutOfRangeException) {
cpuLabel.Text="CPU: "+cpusage+"%";
}
};
cpuLabel.Invoke(m);
...
}
Have a look of SynchronizationContext and also Control.InvokeRequired.
Again, avoid try-catch if there's a better way to check for possible errors.
#competent_tech's answer is good, but I'd like to add a little bit.
There are some cases that a try-catch block would still throw:
You did not catch the exact exception it thrown
The handler rethrows the original exception
The handler causes another exception
In your case, it hits the catch block and did not rethrow the original one, that is, it met the third circumstance: the handler causes another exception.
If you can address the problem causes the exception and avoid it , then don't design it in this way.
Mr. Lippert wrote a good article about the exceptions, you might want to have a look at:
http://ericlippert.com/2008/09/10/vexing-exceptions/
The issue is being caused by this code:
cpusage.Remove(cpusage.IndexOf('.')
You need to ensure that cpusage has length and contains a '.' before attempting to call .Remove.
You can prove this by running a simple app test:
var cpuusage = "0";
System.Diagnostics.Debug.WriteLine(cpuusage.Remove(cpuusage.IndexOf('.')));
This will throw the ArgumentOutOfRangeException exception.
If you modify the code to be:
var cpuusageforlabel = "CPU: ";
if (!string.IsNullOrEmpty(cpuusage)) {
var index = cpuusage.IndexOf('.');
if (index != -1) {
cpuusageforlabel += cpuusage.Remove(index);
} else {
cpuusageforlabel += cpuusage;
}
} else {
cpuusageforlabel += "0";
}
cpuusageforlabel += "%";
cpuLabel.Invoke((MethodInvoker)(() => cpuLabel.Text = cpuusageforlabel));
You address the exception and won't have to catch the argument out of range exception.
Most probable reason is that cpusage is null or empty or without .. So when you get exception and try to use same variable again, you get the second exception.
Check cpusage before using it and don't use catch the way you are using.
I have been writing .NET applications and have been impressed with the error handling included in the framework.
When catching an error that has been throw by the processes or somewhere in the code I like to include the message (ex.Message, which is usually pretty general) but also the stacktrace (ex.stacktrace) which helps to trace the problem back to a specific spot.
For a simple example let's say for instance that we are recording numbers to a log in a method:
public void ExampleMethod(int number){
try{
int num = number
...open connection to file
...write number to file
}
catch(Exception ex){
.... deal with exception (ex.message,ex.stacktrace etc...)
}
finally{
...close file connection
}
}
Is there any way to see the method called (in this case ExampleMethod) with the specific number that was passed that potentially crashed the method call? I believe you could log this perhaps in the catch block but I am interested essentially in catching the method call and parameters that caused the system to throw the exception.
Any ideas?
I suggest stuffing the parameter values into the exception's Data dictionary, e.g.
public void ExampleMethod(int number) {
try {
int num = number
...open connection to file
...write number to file
}
catch(Exception ex) {
ex.Data["number"] = number;
//.... deal with exception (ex.message,ex.stacktrace etc...)
}
finally {
//...close file connection
}
Another advantage of this method is that you can stuff the parameters in the catch block, then re-throw the exception and log it somewhere else without losing the stack trace, e.g.
catch(Exception ex) {
ex.Data["number"] = number;
throw;
}
If you want to know the value of the parameters in your method, then there is only one way, IMO, to do it - you need to repackage the exception with data.
For example:
int param1 = 10;
string param2 = "Hello World";
try
{
SomeMethod(param1, param2)
}
catch(SomeExpectedException e)
{
throw new MyParameterSensitiveException(e, param1, param2);
}
You basically repackage the original exception as the inner exception of another exception, and additionally supply the parameters you used to call the method. Then you could inspect that in some way to figure out what went wrong.
The accepted answer and many of the solutions described will work fine but what you're doing is littering your source with a slightly different blob of code depending on what parameters are in your method signature.
When it comes time to add a new parameter you need to remember to update your handler to add that new parameter. Or if you remove a parameter then you need to remember to remove the parameter from your exception handler.
What if you have a two or more try..catch blocks? Then you now have two blocks of code to keep up to date. Definitely not refactor friendly.
Another approach is to remove the logging code use a technique called Aspect Oriented Programming.
One such tool to facilitate this is a product called PostSharp.
With PostSharp you can write a logger than is invoked whenever an exception is thrown without the need for messy method and parameter specific code. For example (using version 1.5 of PostSharp):
LoggerAttribute.cs -
[Serializable]
public class LoggerAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
Console.WriteLine(eventArgs.Method.DeclaringType.Name);
Console.WriteLine(eventArgs.Method.Name);
Console.WriteLine(eventArgs.Exception.StackTrace);
ParameterInfo[] parameterInfos = eventArgs.Method.GetParameters();
object[] paramValues = eventArgs.GetReadOnlyArgumentArray();
for (int i = 0; i < parameterInfos.Length; i++)
{
Console.WriteLine(parameterInfos[i].Name + "=" + paramValues[i]);
}
eventArgs.FlowBehavior = FlowBehavior.Default;
}
}
You then decorate your classes with the LoggerAttribute:
[Logger]
public class MyClass
{
public void MyMethod(int x, string name)
{
// Something that throws an exception
}
}
Anything that throws an exception in MyMethod will cause the OnException method to be executed.
There are two versions of PostSharp. Version 1.5 is free and open sourced under the GPL and is targeted at .NET 2.0. PostSharp 2.0 is not entirely free but its community edition will support the basic functionality described above.
In order to do this:
public void MyProblematicMethod(int id, string name)
{
try
{
object o = null;
int hash = o.GetHashCode(); // throws NullReferenceException
}
catch (Exception ex)
{
string errorMessage = SummarizeMethodCall(MethodBase.GetCurrentMethod(), id, name);
// TODO: do something with errorMessage
}
}
...and get this:
"MyProblematicMethod invoked: id = 1, name = Charlie"
...you could do something like this:
public static string SummarizeMethodCall(MethodBase method, params object[] values)
{
var output = new StringBuilder(method.Name + " invoked: ");
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
output.AppendFormat("{0} = {1}",
parameters[i].Name,
i >= values.Length ? "<empty>" : values[i]
);
if (i < parameters.Length - 1)
output.Append(", ");
}
return output.ToString();
}
You could make a class that inherits Exception and add some arguments to it so you could pass the number to it.
You can get the method name and the parameters like this,
try
{
int a = 0;
int i = 1 / a;
}
catch (Exception exception)
{
StackTrace s = new StackTrace(exception);
StackFrame stackFrame = s.GetFrame(s.FrameCount - 1);
if (stackFrame != null)
{
StringBuilder stackBuilder = new StringBuilder();
MethodBase method = stackFrame.GetMethod();
stackBuilder.AppendFormat("Method Name = {0}{1}Parameters:{1}", method.Name, Environment.NewLine);
foreach (ParameterInfo parameter in method.GetParameters())
{
stackBuilder.AppendFormat("{0} {1}", parameter.ParameterType.FullName, parameter.Name);
stackBuilder.AppendLine();
}
// or use this to get the value
//stackBuilder.AppendLine("param1 = " + param1);
//stackBuilder.AppendLine("param2 = " + param2);
}
}
I am not sure whether you can get the parameter values directly off the stack like a debugger.
The Automatic Exception Handling from Crypto Obfuscator can do what you need.
The exception reports include all pertinent information including full stack trace info along with the values of all method arguments and local variables, plus the system information, the time of the exception, the build number, and optional developer defined custom data like log files, screenshots, etc.
DISCLAIMER: I work for LogicNP Software, the developer of Crypto Obfuscator.
I need to find ways to add retry mechanism to my DB calls in case of timeouts, LINQ to SQL is used to call some sprocs in my code...
using (MyDataContext dc = new MyDataContext())
{
int result = -1; //denote failure
int count = 0;
while ((result < 0) && (count < MAX_RETRIES))
{
result = dc.myStoredProc1(...);
count++;
}
result = -1;
count = 0;
while ((result < 0) && (count < MAX_RETRIES))
{
result = dc.myStoredProc2(...);
count++;
}
...
...
}
Not sure if the code above is right or posed any complications.
It'll be nice to throw an exception after MAX_RETRIES has reached, but I dunno how and where to throw them appropriately :-)
Any helps appreciated.
If you get a timeout from your database, it's not very likely that it's going to respond in a timely fashion a few miliseconds later.
Retrying in a tight loop as you suggest is likely to make a bad situation worse because you would be placing an undue burden on the database server, as well as tying up a thread in the calling code. It would be safer to introduce a wait time between each retry.
For more advanced scenarios, you could consider a progressive wait pattern where you retry more frequently in the beginning and then with longer and longer intervals if you still get timeouts.
You may also want to look into the Circuit Breaker design pattern from the book Release It!, as well as many of the other patterns and anti-patterns described in that book.
The State pattern is a good fit for implementing Circuit Breaker.
Personally, I would use recursion here. It makes for cleaner code since the only "extra code" you have is a parameter into a function. For example:
private MyResult Foo(MyParameters mp, int repeatCall)
{
var result = null;
try
{
result = mp.dc.myStoredProc(...);
}
catch (MyException err)
{
if (repeatCall > 0)
{
result = Foo(mp, repeatCall - 1);
}
else
{
throw;
}
}
return result;
}
This is an ideal example for recursion, I think. Whatever is calling this need not be concerned with the looping and it makes MUCH cleaner code.
As Mark Seemann corrrectly mentioned, it's not a good idea to use a retry policy to deal with with timeouts. However, given a delay this might be a good idea after all. To implement it, you can use a custom action invoker that executes your action method and takes care of retries in case of an SQL exception. This way you don't have to take care of the retry policy in each and every action method's code.
We don't have database timeout in our system, but I am using the same technique to handle sql read deadlocks in a generic way.
We use something like this (prefer that a new EF Context is instantiated for each retry):
Sorry but the code for SqlExceptionUtil.IsSqlServerErrorType() could not be included (overly custom and many layers).
static public T ExecuteRetryable<T>(
Func<T> function,
out int actualAttempts,
string actionDescriptionForException = "SQL",
int maxTries = 3,
int pauseMaxMillis = 1000,
int pauseMinMillis = 0,
bool alsoPauseBeforeFirstAttempt = false,
bool allowRetryOnTimeout = false)
{
Exception mostRecentException = null;
for (int i = 0; i < maxTries; i++)
{
// Pause at the beginning of the loop rather than end to catch the case when many servers
// start due to inrush of requests (likely). Use a random factor to try and avoid deadlock
// in the first place.
//
if (i > 0 || alsoPauseBeforeFirstAttempt)
Thread.Sleep(new Random
(
// Default Initializer was just based on time, help the random to differ when called at same instant in different threads.
(Int32)((DateTime.Now.Ticks + Thread.CurrentThread.GetHashCode() + Thread.CurrentThread.ManagedThreadId) % Int32.MaxValue)
)
.Next(pauseMinMillis, pauseMaxMillis));
actualAttempts = i + 1;
try
{
T returnValue = function();
return returnValue;
}
catch (Exception ex)
{
// The exception hierarchy may not be consistent so search all inner exceptions.
// Currently it is DbUpdateException -> UpdateException -> SqlException
//
if (!SqlExceptionUtil.IsSqlServerErrorType(ex, SqlServerErrorType.Deadlock) &&
(!allowRetryOnTimeout || !SqlExceptionUtil.IsSqlServerErrorType(ex, SqlServerErrorType.Timeout)))
throw;
mostRecentException = ex;
}
}
throw new Exception(
"Unable to perform action '" + actionDescriptionForException + "' after " + maxTries +
" tries with pauses of [" + pauseMinMillis + "," + pauseMaxMillis + "]ms due to multiple exceptions.",
mostRecentException);
}
Usage:
List<SomeTableEntity> result = DatabaseHelpers.ExecuteRetryable<List<SomeTableEntity>>(() =>
{
using (EfCtx ctx = new EfCtx())
{
return ctx.SomeTable.Where(...).ToList()
}
}, out int actualAttempts, allowRetryOnTimeout: true);
It would be nice if someone would show how to disguise the wrapping code behind a custom Linq construct like: WithRetry(...).