Catching multiple exceptions in console app using one try{...}catch{...} block - c#

I would like ask you to explain me how the exception system works in the following piece of code:
static void Main(string[] args)
{
try
{
//Code which throws exceptions from time to time and runs in a loop
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}
I noticed something which surprised me. When an exception is thrown, the code inside try{...} block is still running and can throw even more exceptions which will be printed to the console window.
Shouldn't the code inside the loop finish its execution and "jump" to Console.ReadKey() at the end?
#EDIT:
The code inside is complicated and it would take a few pages. I can tell you that I make multiple asynchronous operations inside like downloading files, receiving packets, etc. In other words there are other threads which are created in the loop.
#EDIT2:
Presumably this is the code responsible for the behavior:
public SomeConstructor(Socket server)
{
_pb = new PacketBuilder(server, c);
SocketWrapper sw = new SocketWrapper(server, Globals.recvBufferSize);
sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None,PacketReceiveCallback, sw);
_pi = new PacketInterpreter(this, c);
}
private void PacketReceiveCallback(IAsyncResult iar)
{
SocketWrapper sw = iar.AsyncState as SocketWrapper;
int bytesReceived = sw.Socket.EndReceive(iar);
_pi.Interpret(sw.Buffer, 0, bytesReceived);
if (bytesReceived > 0)
sw.Socket.BeginReceive(sw.Buffer, 0, Globals.recvBufferSize, SocketFlags.None, PacketReceiveCallback, sw);
}

Code inside try block will execute as long as it doesn't throw an exception. If the exception throw within your try block the following code will not execute and it will jump to catch block.
static void Main(string[] args)
{
try
{
//Code which throws exceptions from time to time and runs in a loop
Console.WriteLine("Line 1");
throw new Exception("Sample Exception"); // your code will stop here and following line will not prine.
Console.WriteLine("This line will not print");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}

The only reason I can think of why you would get such a behavior is if you're starting new threads inside your try block. So if you're starting any new threads or using the task parallell library or plinq, you might get something like that.
But it's really hard to inspection-debug code that was replaced by a comment...

Related

C# Application does not crash in VS BUT CRASH on system running

I'm developing a simple test tool to verify how many HASH(SHA1) the customer server can elaborate in 1 second.
The attached sample use muti-threading to start and stop a timer that counts executed HASH.
The HASHes are sequential.
The application works well in Visual Studio, but if I run it outside the VS environment it crashes.
The problem is on increment() function in "using" section. If I comment it, everything works well!
static void increment()
{
try
{
using (SHA1 sha = new SHA1CryptoServiceProvider())
{
byte[] result;
byte[] data = new byte[20];
new Random().NextBytes(data);
result = sha.ComputeHash(data);
}
Interlocked.Increment(ref safeInstanceCount);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The code used to start and stop the time is the following:
bool stop;
static void Main()
{
try {
TimerQueueTimer qt;
qt = new TimerQueueTimer();
TimerQueueTimer.WaitOrTimerDelegate CallbackDelete = new TimerQueueTimer.WaitOrTimerDelegate(QueueTimerCallback);
uint dueTime = uint.Parse(textBox1.Text); // string "60000" = 1 min
uint period = 0;
qt.Create(dueTime, period, CallbackDelete);
while (!stop)
{
// Thread thread = new Thread(new ThreadStart(increment));
// thread.IsBackground = true;
// thread.Start();
increment();
}
stop = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void QueueTimerCallback(IntPtr pWhat, bool success)
{
try
{
stop = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
How can I understand where is the error?
=
The application crashes without any exception.
I try to catch it, without success, it happened after 60 sec. (Maybe QueueTimerCallback is called?)
The application does not generate any error trace and it DOES not crash running under Visual Studio!
When it crashes it does not generate any stack trace, just a pop-up crash window giving in detail the "StackHash_xxxxx" error
Nothing to do! I've try to use Console.Read (it's a Windows app not console) but I cannot see anything. Here is the error shown! https://picasaweb.google.com/lh/photo/iHsBhRSy-DNTYVo4CpoeA9MTjNZETYmyPJy0liipFm0?feat=directlink
Your program is likely throwing an exception, and it's getting written to the console, but you don't have anything from stopping the console from closing immediately after the message is written.
Add a Console.ReadKey(); after your try/catch block.

Delegate - Exceptions don't wait until calling EndInvoke()

I have this code:
using System;
using System.Runtime.Remoting.Messaging;
class Program {
static void Main(string[] args) {
new Program().Run();
Console.ReadLine();
}
void Run() {
Action example = new Action(threaded);
IAsyncResult ia = example.BeginInvoke(new AsyncCallback(completed), null);
// Option #1:
/*
ia.AsyncWaitHandle.WaitOne();
try {
example.EndInvoke(ia);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
*/
}
void threaded() {
throw new ApplicationException("Kaboom");
}
void completed(IAsyncResult ar) {
// Option #2:
Action example = (ar as AsyncResult).AsyncDelegate as Action;
try {
example.EndInvoke(ar);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
In many articles stands that when I call BeginInvoke, all Exceptions (here from method threaded) wait until I call EndInvoke and will be thrown there. But it doesn't work, the Exception ("Kaboom") is "unhandled" and the program crashes.
Can you help me?
Thanks!
That works fine. When you say "and the program crashes", I'm wondering if you just have the IDE set to break on all exceptions. I get no crash with that - it writes "Kaboom" to the console, as we would expect. Try running it outside of the IDE or pressing ctrl+f5 instead of just f5.
I think you are just seeing the IDE being "helpful":
Ignore that; the IDE doesn't always get it right. That is still handled.

Why is this finally not executing?

.net 4 console app sample
When I run this in the vs 2010 it seems to keep throwing (from the catch) and never gets to the finally. It breaks on the throw and shows the exception, I hit f5 and it rethrows almost like its looping on the throw. Using similiar code in another exe I was able to throw the exception to the console and execute the finally to clean up. That is not the case not and I'm wondering why.
static void Main(string[] args)
{
try
{
throw new Exception("Exception");
}
catch(Exception)
{
Console.WriteLine("Catch");
throw;
}
finally
{
Console.WriteLine("Finally");
}
}
On the contrary, it does execute the finally block. This is the output:
Catch
Unhandled Exception: System.Exception: Exception at ConsoleApplication1.Program.Main(String[] args) in C:\Desktop\ConsoleApplication1\Program.cs:line 24
Finally
I would bet the finally actually is executed, but being in the Main method of the console application, in the finally the console object is not available anymore.
If I start the program with debugging, the code stops with the message "unhandled exception", which is before finally would be executed. Running without debugging will work as intended (CTRL-F5).
Using the debugger you can verify the finally being executed by moving your testcode inside another try-catch block, e.g.:
static void Main(string[] args)
{
try
{
Method();
}
catch (Exception)
{
Console.WriteLine("caught in main");
}
Console.ReadKey();
}
public static void Method()
{
try
{
throw new Exception("Exception");
}
catch (Exception)
{
Console.WriteLine("Catch");
throw;
}
finally
{
Console.WriteLine("Finally");
}
}
You can guarantee that it is indeed executing, as #David Heffernan demonstrated with his output; however, you might consider what is said in the C# specification (8.10) in order be confident that is should be:
The statements of a finally block are always executed when control
leaves a try statement. This is true whether the control transfer
occurs as a result of normal execution, as a result of executing a
break, continue, goto, or return statement, or as a result of
propagating an exception out of the try statement.

Process is terminated due to StackOverflowException

This is difficult situation to explain. Have a service process that starts 2 threads, each thread loops forever but sleeps for 5 minutes each once the payload is finished.
Problem is that my second thread terminates well before the payload is even finished, for no apparent reason, and i also can't catch the exception as it seems to be triggered from outside the delegate process?
Any suggestions on how to find the problem?
The code....
public void StartService()
{
ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
ThreadStart stSend = new ThreadStart(SendNewMail);
senderThread = new Thread(stRecieve);
recieverThread = new Thread(stSend);
sendStarted = true;
recieveStarted = true;
senderThread.Start();
recieverThread.Start();
}
private void DownloadNewMail()
{
while(recieveStarted)
{
//Payload....
if (recieveStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
private void SendNewMail()
{
while(sendStarted)
{
//Payload....
if (sendStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
Try to check callstack lenght in your code:
class Program
{
static void Main(string[] args)
{
try
{
Hop();
}
catch (Exception e)
{
Console.WriteLine("Exception - {0}", e);
}
}
static void Hop()
{
CheckStackTrace();
Hip();
}
static void Hip()
{
CheckStackTrace();
Hop();
}
static void CheckStackTrace()
{
StackTrace s = new StackTrace();
if (s.FrameCount > 50)
throw new Exception("Big stack!!!!");
}
}
If you are having trouble following the flow of your application's code execution, try logging the entrance of methods with a timestamp and threadid.
Also, You can't catch the exception because it is a StackOverflowException.
See msdn: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. "
Do you utlize any heavy-weight library for tasks like DownloadNewMail and SendNewMail? For example I encountered StackOverflows when running large jobs using Microsoft.SqlServer.Dts.Runtime.Package. Try running the same workload sequentially inside a command-line application to see if the issue persists.

Order of execution of try catch and finally block

I am confused about the order of try, catch and finally block execution.
I also want to know when should I use try-catch block and what should I put in the try-catch block?
I also want to know if some exception comes in try block then if an action is taken corresponding to try block then which one is executed first catch or finally (which is always to be executed)?
After the execution of these two does control return to try block or it leave it?
If you have (note: this is not valid C#, see below for a valid example):
try {
// ... some code: A
} catch(...) {
// ... exception code: B
} finally {
// finally code: C
}
Code A is going to be executed. If all goes well (i.e. no exceptions get thrown while A is executing), it is going to go to finally, so code C is going to be executed. If an exception is thrown while A is executed, then it will go to B and then finally to C.
As an example, here's a valid C# code block from http://msdn.microsoft.com/en-us/library/dszsf989.aspx:
public class EHClass
{
void ReadFile(int index)
{
// To run this code, substitute a valid path from your local machine
string path = #"c:\users\public\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
// Do something with buffer...
}
}
The reason to use try/catch/finally is to prevent your program to fail if there is an error in some code (A in the above example). If there is a problem, you can use catch part to catch the problem and do something useful, such as inform the user, log the exception to a log file, try again or try something different that you suppose might work instead of what you tried originally.
finally is used to ensure that some cleanup is performed. E.g. in A you might try to open a file and read it. If opening succeeds, but read fails, you will have an open file dangling. What you would like in that case is to have it closed, which you would do in finally block - this block always gets executed, guaranteeing the closing of the file.
Take a look here for more info:
http://msdn.microsoft.com/en-us/library/0yd65esw.aspx
http://www.c-sharpcorner.com/UploadFile/puranindia/75/Default.aspx
A try ... catch block is used to catch exceptions. In the try block you put the code that you expect may raise an exception.
If no exception occurs then the code in the try block completes as expected. If there's a finally block then that will execute next.
If an exception does occur then execution jumps to the start of the first matching catch block. Once that code is complete the finally block (if it exists) is executed. Execution does not return to the try block.
You should almost never use try/catch.
You should only catch exceptions that you can actually correct, and only when you're expecting them. Otherwise, let the caller handle the exception - or not.
If used, any catch clauses are executed first - only one of them.
Then, finally is "finally" executed.
This has been stated better in many places, but I'll try. The following code:
try
{
// Do something here
}
catch (Exception ex)
{
MessageBox.Show("Friendly error message");
}
does not fix the exception. It hides the exception so that the problem will never be fixed. That code has no idea which exception was thrown, because it will catch all of them, and it does nothing to correct the problem - it just tells the user a polite fiction.
The fact of the matter is that the code above should be replaced with the following:
// Do something here
This way, if the caller of this method knows how to fix particular problems, then the caller can fix them. You will not have removed that option from the caller.
If the caller does not know how to fix the problem, then the caller should also not catch the exception.
Here is an example (from MSDN) of using exceptions in a reasonable manner. It's a modified form of the example in the documentation of the SmtpFailedRecipientsException Class.
public static void RetryIfBusy(string server)
{
MailAddress from = new MailAddress("ben#contoso.com");
MailAddress to = new MailAddress("jane#contoso.com");
using (
MailMessage message = new MailMessage(from, to)
{
Subject = "Using the SmtpClient class.",
Body =
#"Using this feature, you can send an e-mail message from an application very easily."
})
{
message.CC.Add(new MailAddress("Notifications#contoso.com"));
using (SmtpClient client = new SmtpClient(server) {Credentials = CredentialCache.DefaultNetworkCredentials})
{
Console.WriteLine("Sending an e-mail message to {0} using the SMTP host {1}.", to.Address, client.Host);
try
{
client.Send(message);
}
catch (SmtpFailedRecipientsException ex)
{
foreach (var t in ex.InnerExceptions)
{
var status = t.StatusCode;
if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable)
{
Console.WriteLine("Delivery failed - retrying in 5 seconds.");
System.Threading.Thread.Sleep(5000); // Use better retry logic than this!
client.Send(message);
}
else
{
Console.WriteLine("Failed to deliver message to {0}", t.FailedRecipient);
// Do something better to log the exception
}
}
}
catch (SmtpException ex)
{
// Here, if you know what to do about particular SMTP status codes,
// you can look in ex.StatusCode to decide how to handle this exception
// Otherwise, in here, you at least know there was an email problem
}
// Note that no other, less specific exceptions are caught here, since we don't know
// what do do about them
}
}
}
Note that this code uses try/catch to surround a small piece of code. Within that try/catch block, if an SmtpException or SmtpFailedRecipientsException is thrown, we know what to do about it. If, for instance, we were to catch IOException, we would not know what it meant, or what to do about it. Any exception you don't actually know how to correct should not be caught, except maybe to add information to the exception, log it, and rethrow.
Here is an example:
try
{
someFunctionThatWorks();
functionThatThrowsAnException(); // As soon as this function throws an exception we are taken to the catch block
anotherFunction(); // <-- This line will never get executed
}
catch(Exception e)
{
// Here you can handle the exception, if you don't know how to handle it you should not be catching it
// After this you will not be taken back to the try block, you will go right to the finally block
}
finally
{
// Code here is always executed at the very end, regardless of whether an exception was thrown or not
}
I'd like to elaborate a bit on this and extend #icyrock.com answer with scenario when you rethrow the exception in the catch block so it is handled lower on the execution stack...
I gave it a try with the following code:
static void Main(string[] args)
{
try
{
// pick one:
// NormalExcecution();
// TroubleExcecution();
}
catch
{
Console.WriteLine("block D");
}
Console.ReadKey();
}
private static void NormalExcecution()
{
try
{
Console.WriteLine("block A");
}
catch (Exception)
{
Console.WriteLine("block B");
throw;
}
finally
{
Console.WriteLine("block C");
}
}
private static void TroubleExcecution()
{
try
{
Console.WriteLine("block A");
throw new Exception();
}
catch (Exception)
{
Console.WriteLine("block B");
throw;
}
finally
{
Console.WriteLine("block C");
}
}
So when there is no exception in block A, then the sequence is as follows (exception handling blocks are never hit):
Block A
Block C
When there's some problem with block A, the sequence is as follows:
block A
block B
block C
block D
Another words, the occurring exception is first handled by block B, then the finally clause is executed, only after that the exception is rethrown and handled lower on the execution stack (block D).
Please mind I may be wrong with what is actually going on under the hood of the .NET framework - I just present the results I observed :)

Categories

Resources