My colleague wrote this code "closeConnection()" below, and its throwing an exception of type:
RaceOnRCWCleanup was detected
An attempt has been made to free an RCW that is in use. The RCW is in
use on the active thread or another thread. Attempting to free an
in-use RCW can cause corruption or data loss.
private static void closeConnection()
{
if(connection != null)
{
try
{
connection.Close(); // <-- this is the problem
}
catch(Exception)
{
}
connection = null;
}
}
Since this code is wrapped in a try { } catch { } block it leads me to conclude that you cannot catch this type of exception. Is this the case?
It is not an exception, it is a debugger warning. It is one of the "managed debugging assistants", designed to catch common mistakes that can cause very difficult to diagnose problems later. So no, you cannot catch it with try/catch. You turn it off with Debug + Exceptions, Managed Debugging Assistants, Thrown checkbox for "RaceOnRCWCleanup".
It can be a false alarm, but you ought to fret about this a bit. The generic diagnostic is that the connection.Close() call is causing a COM object to be released. But it is returning to code that got started by that same COM object, typically due to an event. Which means that it may return to code inside the COM server that is part of a now destroyed COM object. It usually gives a loud bang if that's something the server cannot deal with, typically with a completely undiagnosable AccessViolation. If it doesn't go bang and you tested this thoroughly then go ahead and turn the warning off. Or find a way to call Close() later, check this answer for an example.
You have probably have a race condition, multiple threads can enter your method at the same time. You need to lock so that 2 threads do not enter the same code at the same time e.g.
public static classs SomeClass
{
private static object locker;
private static void closeConnection()
{
if(connection != null)
{
lock(locker)
{
if(connection != null) //might have been set to null by another thread so need to check again
{
try
{
connection.Close(); // <-- this should work now
}
catch(Exception)
{ //Don't swallow an exception here
}
connection = null;
}
}
}
}
RaceOnRCWCleanup is not an exception so you cannot catch it, it is something happening outside the CLR that triggers a debugger attachment request.
Related
I have following code in my web page:
btnTest_Click(object sender, EventArgs e)
{
...
bool ret=myFunc(...);
if (ret)
{...}
else
{
lblStatus.Text="Some Text";
lblStatus.Visible=true;
}
}
private bool myFunc(...)
{
bool ret=false;
try
{
...
ret=true;
}
catch (Exception ex)
{
lblStatus.Text="Other Text";
lblStatus.Visible=true;
}
return ret;
}
If an exception occurs in myFunc, the lblStatus always shows "Some Text" not "Other Text". That means the catch block in myFunc doesn't really mean anything. I wonder how to fix this code to handle the exception better?
update: maybe my example is not very good. But I main purpose is to ask best practices for exceptions handling between calling and being called functions.
Why is your called function setting the label text on exception and the caller setting it on success?
That's something of a mixed metaphor. Let one party be responsible for UI (separation of concerns) while the other is responsible for doing work. If you want your called function to be fault tolerant try something like this:
private bool myFunc(...)
{
bool ret ;
try
{
...
ret=true;
}
catch
{
ret = false ;
}
return ret;
}
Then your caller can do something like:
bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;
if ( success )
{
// do something useful
}
Your catch clause is doing a lot. It catches every exception and "forgets it" suppressing it to the rest of the call stack. This can be perfectly fine but i'll try to explain your options:
You usually have 3 options:
Do not care about exceptions and let code above you handle it
Care to log the exception and let it propagate
The exception has its meaning in a given context and should not be propagated (this is your scenario)
I use all of them.
Option 1
You can just implement your function and if an exception occurs then it means some fault occurred and you just want your application to fail (at least to a certain level)
Option 2
Some exception occurs and you'll want to do one of two (or even both)
log the error
change the exception to another one more meaningful to the caller
Option 3
The exception is expected and you know how to completely react to it. For instance, in your case, i tend to believe you do not care about the type of exception but want a "good default" by setting some controls to a given text.
conclusion
There are no silver bullets. Use the best option for each scenario.
Nevertheless catching and "suppressing" catch(Exception ex) is rare and if seen often it usually means bad programming.
It displays "Some Text" because, when an exception occurs in myFunc, it returns false. Then you go into the else block of the btnTest_Click method, where you set lblStatus.Text to "Some Text" again.
So, basically, you're setting the label's text to "Other text" and then to "Some Text".
The exception handling is just fine. The problem with your code is that you are putting the "Some Text" string in the label if the return value is false, and that is when there was an exception, so it will replace the message from the catch block.
Switch the cases:
if (ret) {
// it went well, so set the text
lblStatus.Text="Some Text";
lblStatus.Visible=true;
} else {
// an exception occured, so keep the text set by the catch block
}
This is a complex question so I will try to break it down
In terms of functions I would try to stick to the Single Responsibility Principal. It should do one, well defined thing.
Exceptions should be that, exceptional. It is then preferable to try not to incur exceptions but obviously to deal with them as and when. For example it is better to test a variable as being null before attempting to use it (which would throw an exception). Exceptions can be slow (especially if a lot are thrown)
I would say that the question of WHERE you handle the exception is down to whose responsibility the exception is. If myFunc were to access a remote server and return a status of true or false you'd expect it to handle its own IO exception. It would probably not handle (or rethrow) any parameter problems. This relates to point 1. It is the functions responsibility deal with the connection process, not to provide the correct parameters. Hiding certain exceptions can cause problems if other people (or a forgetful you) tries to use the code at a later date. For example in this myFunc which makes a connection, should you hide parameter exceptions you may not realise you have passed in bad parameters
If you want to be informed of encountering a specific type of error inside one of your functions, I'd recommend inheriting Exception and creating your own exception class. I'd put a try-catch block inside your btnTest_Click() handler, and then I'd look to catch your custom exception class. That way, you won't lose the opportunity to detect any errors happening inside your myFunc() function.
I usually setup an error handling system. Here's a simple way, but this can be wrapped up into a base class. I can show you that if you need.
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}
The following code is from MSDN:
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
private Dictionary<int, string> innerCache = new Dictionary<int, string>();
public void Add(int key, string value)
{
cacheLock.EnterWriteLock();
try
{
innerCache.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
}
I've seen code like this in other places.The EnterWriteLock() is always outside the try block. Does anyone know why it's not inside the try block?
Suppose the EnterWriteLock() fails. For whatever reason.
Then the one thing you shouldn't do is to Exit a lock you never Entered.
It's a very basic pattern that also holds for example for streams, but not seen as often thanks to the using() {} statement.
var s = File.Create(...);
// (only) if the previous line succeeded,
// we gain the responsibility to close s, no matter what
try
{
// do some I/O
}
finally
{
s.Dispose();
}
Because that would be a bug. You can't call ExitWriteLock until you're sure that you entered it. Imagine what happens if you moved it inside try {} and EnterWriteLock() throws an exception. That's a double kaboom. Kabloom, screws up the exception message.
If EnterWriteLock throws an exception, there is no need to call ExitWriteLock, hence the reason it is not in the try block. ExitWriteLock should always be called if EnterWriteLock is successfully invoked. You may want to wrap a try block around EnterWriteLock in certain scenarios as it can throw a LockRecursionException. ExitWriteLock can also throw a SynchronizationLockException and may require a try block in your application.
I've been wrapping all the code that invoke WCF calls within an using statement in a thought that the object will be disposed properly. When I'm googling for an exception "Http service located at .. is too busy" I found this link http://msdn.microsoft.com/en-us/library/aa355056.aspx that says should not use using statement in typed proxies. Is that really true? I think I got a big code change (sigh). Is this problem comes only in typed proxies?
Sample code:
private ServiceClient proxy;
using(proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc")){
string result = proxy.Method();
}
The core of the problem is: at the end of your using block (which generally is a very good idea to have!), the WCF proxy will be disposed. However, during disposing of the WCF proxy, exceptions can occur - and those will cause the app to misbehave. Since this is done implicitly at the end of the using block, you might not even really see where the error occurs.
So typically, Microsoft recommends a pattern something like this:
private ServiceClient proxy;
try
{
proxy = new ServiceClient("ConfigName", "http://serviceaddress//service.svc");
string result = proxy.Method();
proxy.Close();
}
catch (CommunicationException e)
{
// possibly log error, possibly clean up
proxy.Abort();
}
catch (TimeoutException e)
{
// possibly log error, possibly clean up
proxy.Abort();
}
catch (Exception e)
{
// possibly log error, possibly clean up
proxy.Abort();
throw;
}
You need to call the proxy.Close() method explicitly and be prepared to handle any exceptions that might occur from that call, too.
Wrap the proxy operation and instantiation calls up in a class implementing IDisposable. When disposing, check the state property of the proxy and tidy up the channel before closing.
public void Dispose()
{
if (this.MyProxy != null && this.MyProxy.State == CommunicationState.Faulted)
{
this.MyProxy.Abort();
this.MyProxy.Close();
this.MyProxy = null;
}
// ...more tidyup conditions here
}
I like the approach from the comment from "Eric" on this blog (which is similar to another article: http://redcango.blogspot.com/2009/11/using-using-statement-with-wcf-proxy.htm):
"Personally, I like to create my own partial class for the client and override the Dispose() method. This allows me to use the ‘using’ block as I normally would.
public partial class SomeWCFServiceClient : IDisposable
{
void IDisposable.Dispose()
{
if (this.State == CommunicationState.Faulted)
{
this.Abort();
}
else
{
this.Close();
}
}
}
This is somewhat of a follow up to a previous question I had asked, although I am now able to provide a lot more code to improve my question and further show my trouble with this area.
I have three routines here. Two of these routines work together - and if successful, will load an assembly into memory using System.Reflection. I would like for these routines to return an error if the file did not load properly into memory, but for some reason these try-catch statements simply will not work the way I would like.
Note: For this routine to work the file must be a .net assembly. If, for example, the file was programmed in VB6 an error will be thrown. This is the error I am trying to have returned to me.
private void ExecuteDataIntoMemory(string filePath)
{
byte[] bytes = File.ReadAllBytes(filePath);
try
{
ExecFile(bytes);
MessageBox.Show("successfully loaded this file into memory");
}
catch
{
MessageBox.Show("Could not load this file into memory");
}
}
private static void ExecFile(byte[] data)
{
try
{
//Work around for "SetCompatibleTextRenderingDefault"
System.Threading.Thread T = new System.Threading.Thread(ExecFile);
//Set STA to support drag/drop and dialogs?
T.SetApartmentState(System.Threading.ApartmentState.STA);
T.Start(data);
}
catch
{
MessageBox.Show("caught some error ...");
}
}
private static void ExecFile(object o)
{
System.Reflection.MethodInfo T = System.Reflection.Assembly.Load((byte[])o).EntryPoint;
if (T.GetParameters().Length == 1)
T.Invoke(null, new object[] { new string[] { } });
else
T.Invoke(null, null);
}
I can clarify more if necessary but I'm not sure what other information to include at this point.
Use the "throw" statement within the catch statement of ExecFile to raise the same "exception" (or error) caught in ExecFile. For example:
catch {
throw;
}
I think I figured out the problem though. ExecFile(byte[]) starts the thread and returns immediately without waiting for the thread to exit. To allow that method to wait for the thread to exit, add:
T.Join();
right after starting the thread. (To avoid possible ambiguity, however, you should rename ExecFile(object). I'm also not sure whether ExecFile(byte[]) will catch the exception from ExecFile(object).)
If I understand you well, You want the ExecuteDataIntoMemory to be evaluated only if the ExecFile succeed.
1- You are running a new thread to execute the ExecFile method which will be executed in a different thread. So first at the try block in ExecFile(byte[] data) run the ExecFile(data) without a new Thread because you want to wait for it any way:
try
{
ExecFile(data);
}
2- Notice that you have two method with the same name 'ExecFile(byte[] data)' and ExecFile(object o) the data you are passing is from type byte[] so it will be infinite recursive or till stack over flow exception is raised. So you should cast data to object and then pass it to the method i.e:
try
{
ExecFile((object)data);
}
3- At the catch block of the ExecFile(byte[] data) method rethrow the exception so it can be handled from the caller method two i.e:
try
{
ExecFile((object)data);
}
catch
{
MessageBox.Show("caught some error ...");
throw;
}
If you catch the Exception in ExecFile(byte[] data) it won't be propagated in your parent method (ExecuteDataIntoMemory(string filePath)), and then won't be catched again
If you really need to catch your exception twice, rewrite your child method this way
private static void ExecFile(byte[] data)
{
try
{
//Work around for "SetCompatibleTextRenderingDefault"
System.Threading.Thread T = new System.Threading.Thread(ExecFile);
//Set STA to support drag/drop and dialogs?
T.SetApartmentState(System.Threading.ApartmentState.STA);
T.Start(data);
}
catch (Exception ex)
{
MessageBox.Show("caught some error ...");
throw ex;
}
}
If not, simply not try..catch errors in this method, and the Exception will be propagated..
Just look in the callstack which method call the ExecuteDataIntoMemory method again?
if you are using Visual studio IDE put a breakpoint at the messagebox:
MessageBox.Show("successfully loaded this file into memory");
then simple go to the view menu, from there find the callstack window to display and look at the callstack (show external code to the callstack)
maybe this could help.
The rough way (I think), but should work in your case, is subscribe to
AppDomain.CurrentDomain.UnhandledException
event riased, which will get the exception raised directly from the function ExecFile(object o);
Or create a state machine which is set to NEGATIVE state in case of any exception in ExecFile(object o); method.
Or just do not do it in multithreading :)
using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}
Inside the using block, all is fine with treating exceptions as normal. But what if the constructor of SomeClass can throw an exception?
Put your using into the try catch f.e.
try
{
using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}
}
catch(Exception ex)
{
...
}
Yes, this will be a problem when the constructor throws an exception. All you can do is wrap the using block within a try/catch block. Here's why you must do it that way.
using blocks are just syntactic sugar and compiler replaces each using block with equivalent try/finall block. The only issue is that the compiler does not wrap the constructor within the try block. Your code after compilation would have following conversion in the IL.
//Declare object x of type SomeClass.
SomeClass x;
//Instantiate the object by calling the constructor.
x = new SomeClass("c:/temp/test.txt");
try
{
//Do some work on x.
}
finally
{
if(x != null)
x.Dispose();
}
As you can see from the code, the object x will not be instantiated in case when the constructor throws an exception and the control will not move further from the point of exception raise if not handled.
I have just posted a blog-post on my blog on this subject last night.
I'm just now wondering why C#
designers did not wrap object
construction within the try block
which according to me should have been
done.
EDIT
I think I found the answer why C# does not wrap object construction into try block generated in place of the using block.
The reason is simple. If you wrap both declaration and instantiation within the try block then the object would be out of scope for the proceeding finally block and the code will not compile at because, for finally block the object hardly exists. If you only wrap the construction in the try block and keep declaration before the try block, even in that case the it will not compile since it finds you're trying to use an assigned variable.
I threw a quick test program together to check this, and it seems that the Dispose method does not get called when an exception is thrown in the constructor;
class Program
{
static void Main(string[] args)
{
try
{
using (OtherClass inner = new OtherClass())
{
Console.WriteLine("Everything is fine");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.Read();
}
}
class OtherClass : IDisposable
{
public OtherClass()
{
throw new Exception("Some Error!");
}
void IDisposable.Dispose()
{
Console.WriteLine("I've disposed my resources");
}
}
Output :
Some Error!
If you don't throw the exception..
Output :
Everything is fine
I've disposed my resources
Presumably this is because the object was never created, so there's nothing to call Dispose on.
I'm not sure what would happen if the constructor had already allocated some resources which would normally require a proper clean up through Dispose and the exception occurred afterwards though.
This should not be a problem with a well-designed class. Remember the overall question:
public class HoldsResources : IDisposable
{
public HoldsResources()
{
// Maybe grab some resources here
throw new Exception("whoops");
}
}
using (HoldsResources hr = new HoldsResources())
{
}
So, the question is, what should you do about the resources allocated by the HoldsResources constructor before it threw an exception?
The answer is, you shouldn't do anything about those resources. That's not your job. When it was decided that HoldsResources would hold resources, that brought the obligation to properly dispose of them. That means a try/catch/finally block in the constructor, and it means proper implementation of IDisposable to dispose of those resources in the Dispose method.
Your responsibility is to use the using block to call his Dispose method when you're through using the instance. Nothing else.
When you get a hold of resources in the ctor that are not subject to garbage collection, you have to make sure to dispose of them when things go south.
This sample shows a ctor which will prevent a leak when something goes wrong, the same rules apply when you allocate disposables inside a factory method.
class Sample
{
IDisposable DisposableField;
...
public Sample()
{
var disposable = new SomeDisposableClass();
try
{
DoSomething(disposable);
DisposableField = disposable;
}
catch
{
// you have to dispose of it yourself, because
// the exception will prevent your method/ctor from returning to the caller.
disposable.Dispose();
throw;
}
}
}
Edit: I had to change my sample from a factory to a ctor, because apparantly it wasn't as easy to understand as I hoped it would be. (Judging from the comments.)
And of course the reason for this is: When you call a factory or a ctor, you can only dispose of its result. When the call goes through, you have to assume that everything's okay so far.
When calling a ctor or factory you don't have to do any reverse-psychoanalysis to dispose of anything you can't get hold of anyways. If it does throw an exception, it is in the factories/ctor's responsibility to clear anything half-allocated before re-throwing the exception.
(Hope, this time, it was elaborate enough...)