Why use try {} finally {} with an empty try block? - c#

I noticed in System.Threading.TimerBase.Dispose() the method has a try{} finally{} block but the try{} is empty.
Is there any value in using try{} finally{} with an empty try?
http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
bool status = false;
bool bLockTaken = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
}
finally {
do {
if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
bLockTaken = true;
try {
status = DeleteTimerNative(notifyObject.SafeWaitHandle);
}
finally {
m_lock = 0;
}
}
Thread.SpinWait(1);
// yield to processor
}
while (!bLockTaken);
GC.SuppressFinalize(this);
}
return status;
}

From http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/:
This methodology guards against a
Thread.Abort call interrupting the
processing. The MSDN page of
Thread.Abort says that “Unexecuted
finally blocks are executed before the
thread is aborted”. So in order to
guarantee that your processing
finishes even if your thread is
aborted in the middle by someone
calling Abort on your thread, you can
place all your code in the finally
block (the alternative is to write
code in the “catch” block to determine
where you were before “try” was
interrupted by Abort and proceed from
there if you want to).

This is to guard against Thread.Abort interrupting a process. Documentation for this method says that:
Unexecuted finally blocks are executed before the thread is aborted.
This is because in order to recover successfully from an error, your code will need to clean up after itself. Since C# doesn't have C++-style destructors, finally and using blocks are the only reliable way of ensuring that such cleanup is performed reliably. Remember that using block turns into this by the compiler:
try {
...
}
finally {
if(obj != null)
((IDisposable)obj).Dispose();
}
In .NET 1.x, there was a chance that finally block will get aborted. This behavior was changed in .NET 2.0.
Moreover, empty try blocks never get optimized away by the compiler.

Related

Why does deadlock occur on calling Semaphore.WaitOne?

The run() function in the following code is called from other threads simultaneously. At anytime, on any line, a ThreadAbortException might occur according to the general design of the application, which I cannot change.
I sometimes get SemaphoreFullException while calling pool.Release(). I think this occurs if a thread abort exception occurs while calling "pool.WaitOne()". During my debug tries, after SemaphoreFullException has occurred, there is no problem in running the code. After that exception, pool.WaitOne() calls and other things work just as expected.
I haven't been able to get a deadlock situation during my local debug sessions. However, in a remote computer, I have a deadlock with this code. I attach that process using remote debugger and see that the execution is locked on the line pool.WaitOne();.
I can't figure out how this would happen, and what I'm doing wrong. Any help is very appreciated.
private static object poolLocker = new object();
private static Semaphore _pool;
private static Semaphore pool
{
get
{
if (_pool == null)
lock (poolLocker)
if (_pool == null)
{
int count = myMaximumThreadCount;
_pool = new Semaphore(count, count);
}
return _pool;
}
}
private void run()
{
try
{
pool.WaitOne();
do_something_that_may_throw_exception();
}
finally
{
try
{
pool.Release();
}
catch (SemaphoreFullException) { }
}
}
Try to change the initialization of the semaphore object in pool property to:
private static Semaphore pool
{
get
{
if (_pool == null)
lock (poolLocker)
if (_pool == null)
{
int count = myMaximumThreadCount;
_pool = new Semaphore(0, count);
}
return _pool;
}
}
An initial count for this semaphore should be set to zero.
I have found the cause of the deadlock; and it has nothing to do with the question I've asked, so this is a bad question, sorry for that. There seems to be no problem in the code in the question.
The cause: In the do_something_that_may_throw_exception() function, an extern function of a C++ library is being called. When an error occurs in the C++ function, a SEHException is thrown. However, in my tries this exception can only be caught in a function that has HandleProcessCorruptedStateExceptions and SecurityCritical attributes. And that function happens to call the run() function of the question. However, the finally part of the run() function is newer executed! Also, if you have a using(IDisposable object){ ... } and the SEHException occurs inside it; object's Dispose() function won't be called.
I've used the following function for calling the C++ function; and everything worked fine:
SafeCall(()=> call_external_cpp_function());
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
internal static void SafeCall(Action action)
{
try
{
action();
}
catch (System.Threading.ThreadAbortException) { throw; }
catch (System.Threading.ThreadInterruptedException) { throw; }
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

Empty try {}, no catch, filled finally{} in System.Diagnostics.Process sources - what is it good for? [duplicate]

I noticed in System.Threading.TimerBase.Dispose() the method has a try{} finally{} block but the try{} is empty.
Is there any value in using try{} finally{} with an empty try?
http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
bool status = false;
bool bLockTaken = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
}
finally {
do {
if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
bLockTaken = true;
try {
status = DeleteTimerNative(notifyObject.SafeWaitHandle);
}
finally {
m_lock = 0;
}
}
Thread.SpinWait(1);
// yield to processor
}
while (!bLockTaken);
GC.SuppressFinalize(this);
}
return status;
}
From http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/:
This methodology guards against a
Thread.Abort call interrupting the
processing. The MSDN page of
Thread.Abort says that “Unexecuted
finally blocks are executed before the
thread is aborted”. So in order to
guarantee that your processing
finishes even if your thread is
aborted in the middle by someone
calling Abort on your thread, you can
place all your code in the finally
block (the alternative is to write
code in the “catch” block to determine
where you were before “try” was
interrupted by Abort and proceed from
there if you want to).
This is to guard against Thread.Abort interrupting a process. Documentation for this method says that:
Unexecuted finally blocks are executed before the thread is aborted.
This is because in order to recover successfully from an error, your code will need to clean up after itself. Since C# doesn't have C++-style destructors, finally and using blocks are the only reliable way of ensuring that such cleanup is performed reliably. Remember that using block turns into this by the compiler:
try {
...
}
finally {
if(obj != null)
((IDisposable)obj).Dispose();
}
In .NET 1.x, there was a chance that finally block will get aborted. This behavior was changed in .NET 2.0.
Moreover, empty try blocks never get optimized away by the compiler.

Explain "finally"'s use in try-catch-finally blocks

I read that finally key make a try-catch block final work, even function throw exception or not. But I wonder what is different if I don't put a code inside a finally block (like Function_2 below), which is the way I'm using to coding. Thank You!
void Function_1()
{
try
{
throw new Exception();
}
catch
{
}
finally //Have finally block
{
Other_Function();
}
}
void Function_2()
{
try
{
throw new Exception();
}
catch
{
}
Other_Function(); //Don't have finally block
}
if I dont put a code inside a finally block (like Function_2 below)
if you don't put code inside finally , until unless you won't get an exception that code block will be executed.
but if you get an exception before that code block (which was not kept inside finally) will not be executed as the control returns from there itself.
but if you keep your code in finally , it will be executed irrespective of the situation.
Example:1 without finally block
try
{
//throw exption
}
catch
{
//return from here
}
//below statement won't get executed
Other_Function();
Example:2 with finally block
try
{
//throw exption
}
catch
{
//return from here if finally block is not available
//if available execute finally block and return
}
finally
{
//below statement surly gets executed
Other_Function();
}
A finally block, refers to a block of statements that is always executed, regardless of unexpected events or exceptions that may occur during an application's execution. The execution of a finally block is intended to release resources, such as database connections, which are usually available in limited quantities.
From MSDN:
Usually, when an unhandled exception ends an application, whether or
not the finally block is run is not important. However, if you have
statements in a finally block that must be run even in that situation,
one solution is to add a catch block to the try-finally statement.
Alternatively, you can catch the exception that might be thrown in the
try block of a try-finally statement higher up the call stack. That
is, you can catch the exception in the method that calls the method
that contains the try-finally statement, or in the method that calls
that method, or in any method in the call stack. If the exception is
not caught, execution of the finally block depends on whether the
operating system chooses to trigger an exception unwind operation.
Code in finally blocks is always executed. Finally provides a construct for ensuring the correct execution of programs. It ensures a block of statements are always reached before the enclosing method is exited.
his program shows how the finally clause is part of the control flow in programs. In this program, a random number is generated. This value is used to determine whether to throw an exception, immediately return, or do nothing.
using System;
class Program
{
static void Main()
{
try
{
// Acquire random integer for use in control flow.
// ... If the number is 0, an error occurs.
// ... If 1, the method returns.
// ... Otherwise, fall through to end.
int random = new Random().Next(0, 3); // 0, 1, 2
if (random == 0)
{
throw new Exception("Random = 0");
}
if (random == 1)
{
Console.WriteLine("Random = 1");
return;
}
Console.WriteLine("Random = 2");
}
finally
{
// This statement is executed before the Main method is exited.
// ... It is reached when an exception is thrown.
// ... It is reached after the return.
// ... It is reached in other cases.
Console.WriteLine("Control flow reaches finally");
}
}
}
Source

How to gracefully get out of AbandonedMutexException?

I use the following code to synchronize mutually exclusive access to a shared resource between several running processes.
The mutex is created as such:
Mutex mtx = new Mutex(false, "MyNamedMutexName");
Then I use this method to enter mutually exclusive section:
public bool enterMutuallyExclusiveSection()
{
//RETURN: 'true' if entered OK,
// can continue with mutually exclusive section
bool bRes;
try
{
bRes = mtx.WaitOne();
}
catch (AbandonedMutexException)
{
//Abandoned mutex, how to handle it?
//bRes = ?
}
catch
{
//Some other error
bRes = false;
}
return bRes;
}
and this code to leave it:
public bool leaveMutuallyExclusiveSection()
{
//RETURN: = 'true' if no error
bool bRes = true;
try
{
mtx.ReleaseMutex();
}
catch
{
//Failed
bRes = false;
}
return bRes;
}
But what happens is that if one of the running processes crashes, or if it is terminated from a Task Manager, the mutex may return AbandonedMutexException exception. So my question is, what is the graceful way to get out of it?
This seems to work fine:
catch (AbandonedMutexException)
{
//Abandoned mutex
mtx.ReleaseMutex();
bRes = mtx.WaitOne();
}
But can I enter the mutually exclusive section in that case?
Can someone clarify?
According to MSDN the AbandonedMutexException is:
The exception that is thrown when one thread acquires a Mutex object
that another thread has abandoned by exiting without releasing it.
This means that the thread in which this exception was thrown is the new owner of the Mutex (otherwise calling the Mutex.ReleaseMutex Method like you're doing would trigger an ApplicationException), and if you can assure the integrity of the data structures protected by the mutex you can simply ignore the exception and continue executing your application normally.
However, most of the times the AbandonedMutexException is raised the integrity of the data structures protected by the mutex cannot be guaranteed, and that's why this exception was introduced in the version 2.0 of the .NET framework:
An abandoned mutex indicates a serious programming error. When a
thread exits without releasing the mutex, the data structures
protected by the mutex might not be in a consistent state. Prior to
version 2.0 of the .NET Framework, such problems were hard to discover
because no exception was thrown if a wait completed as the result of
an abandoned mutex.

Monitor.TryEnter / Monitor.Exit and SynchronizationLockException

Is it possible to detect if the same thread trying to release the lock?
We have many places in code that looks like:
try
{
try
{
if(!Monitor.TryEnter(obj, 2000))
{
throw new Exception("can not lock");
}
}
finally
{
Monitor.Exit(obj);
}
}
catch
{
//Log
}
The above code very simplified, and actually Enter and Exit statement located in custom object (lock manager).
The problem, that in that structure, we have SynchronizationLockException when trying to "Exit", since it looks like the thread that not succeed to lock, tries to release in finally.
So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?
I thought that I can use CurrentThread.Id to sync enter and exit, but I'm not sure if it "safe" enough.
So the question, is how I can know if the thread who making Monitor.Exit is the same thread who did Monitor.Enter?
You can't, easily, as far as I'm aware. You can't find out which thread owns a monitor.
However, this is just a coding issue - you should change your code so that it doesn't even attempt to release the monitor when it shouldn't. So your code above could be rewritten as:
if (!Monitor.TryEnter(obj, 2000))
{
throw new Exception(...);
}
try
{
// Presumably other code
}
finally
{
Monitor.Exit(obj);
}
Or even better, if you're using .NET 4, use the overload of TryEnter which accepts an ret parameter:
bool gotMonitor = false;
try
{
Monitor.TryEnter(obj, ref gotMonitor);
if (!gotMonitor)
{
throw new Exception(...);
}
// Presumably other code
}
finally
{
if (gotMonitor)
{
Monitor.Exit(obj);
}
}
As you think that to put the calling of Monitor.Exit in try-catch was 'durty'(dirty?), here's a very simple idea trying to 'take the durty away'. Lock is reentrant for the same thread and if one thread acquired successfully, before it releases, attempt from another thread will fail. So that you can consider something like:
public void Exit(object key) {
if(!IsActive) {
return;
}
if(LockDictionary.ContainsKey(key)) {
var syncObject=LockDictionary[key];
if(Monitor.TryEnter(syncObject.SyncObject, 0)) {
SetLockExit(syncObject);
Monitor.Exit(syncObject.SyncObject);
Monitor.Exit(syncObject.SyncObject);
}
}
}
We call Monitor.Exit twice because we lock it twice, one in the code outer, and one just here.
I know this is an older question, but here's my answer anyway.
I would move the try-finally construct inside the if:
try
{
if(Monitor.TryEnter(obj, 2000))
{
try
{
// code here
}
finally
{
Monitor.Exit(obj);
}
}
else
{
throw new Exception("Can't acquire lock");
}
}
catch
{
// log
}

Categories

Resources