How do I know if UdpClient has been closed/disposed? - c#

I am receiving data from UdpClient via the usual async callback:
private void OnUdpData(IAsyncResult result)
{
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}
When I Close() the UdpClient in the main thread, the callback fires as I would expect, but at this point _udpReceive is already disposed and I get an ObjectDisposedException when I try and call EndReceive(). I was expecting to just get an empty buffer.
What is the correct way to handle this? Is there some member of UdpClient I can check before trying to use it, or it the only way to wrap it all in a try{} and catch the ObjectDisposedException? That seems pretty nasty for a normal close.

You can do this to check if its disposed. Client is set to null when the UdpClient is disposed.
private void OnUdpData(IAsyncResult result)
{
if (_udpReceive.Client == null)
return;
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
if (_udpReceive.Client == null)
return;
_udpReceive.BeginReceive(OnUdpData, null);
}
Although because you are closing it in a separate thread you may end up with a race condition. It would be best to just catch ObjectDisposedException and SocketException.
private void OnUdpData(IAsyncResult result)
{
try
{
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}
catch (Exception e)
{
//You may also get a SocketException if you close it in a separate thread.
if (e is ObjectDisposedException || e is SocketException)
{
//Log it as a trace here
return;
}
//Wasn't an exception we were looking for so rethrow it.
throw;
}
}

This is entirely by design. You did something exceptional, you closed the socket even though you expected data to be received. So you'll get an exception. The .NET framework always makes sure that asynchronous calls are completed and that the abort reason is signaled in the callback when you call EndXxx(). Good idea, that lets you clean up any state associated with the callback.
You can make it non-exceptional by waiting until the transfer is complete, stop calling BeginReceive() and then close the socket. But that isn't always practical or sometimes you really want to terminate early. Not a problem, simply catch the ObjectDisposedException and get out. Of course, do consider what happens to the app on the other end of the wire. Anything it sends afterward is going to fall in the bit-bucket with no way for it to find out.

Based on your question, it sounds like you would like to avoid the Exception being thrown when forcing the client to close. I'm going to take some guesses about your code and try to provide a solution:
Since you have a method named "OnUdpData" I'm assuming you have a wrapper class around the UDPClient. In that wrapper class, you could do something like this: Set a flag that indicates that you are closing the client and should no longer use the client immediately before attempting to close the client. This avoids the race condition caused by checking _udpReceive.Client == null before calling EndReceive() since the main thread could close the client after the Client conditional check.
private bool _finishedListening = false;
public void StopListener()
{
_finishedListening = true;
_udpReceive.Close();
}
private void OnUdpData(IAsyncResult result)
{
if (_finishedListening == true)
return;
byte[] data = _udpReceive.EndReceive(result, ref _receiveEndPoint);
//Snip doing stuff with data
_udpReceive.BeginReceive(OnUdpData, null);
}

Related

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.

Checking if an object exists after calling Activator.GetObject

I'm developing a project with passive replication where servers exchange messages among themselves. The locations of each server are well-known by every other server.
So, it may happen that when a server comes up, it will check the other servers, that may haven't come up yet. When I call Activator.GetObject, is it the only way to find out that other servers are down by invoking a method on the object, and expect an IOException (such as the example below)?
try
{
MyType replica = (MyType)Activator.GetObject(
typeof(IMyType),
"tcp://localhost:" + location + "/Server");
replica.ping();
}
catch (IOEXception){} // server is down
I do this and it works most of the times (even though is slow), but sometimes it blocks on a method called NegotiateStream.ProcessRead during the process, and I can't understand why...
When a server is down, the timeout has always been slow for me (using a TcpChannel, which doesn't let you set the timeout properly in .NET Remoting). Below is a workaround for how I use my Ping function (it's likely a bit complex for your needs, so I'll explain the parts that matter for you):
[System.Diagnostics.DebuggerHidden] // ignore the annoying breaks when get exceptions here.
internal static bool Ping<T>(T svr)
{
// Check type T for a defined Ping function
if (svr == null) return false;
System.Reflection.MethodInfo PingFunc = typeof(T).GetMethod("Ping");
if (PingFunc == null) return false;
// Create a new thread to call ping, and create a timeout of 5 secons
TimeSpan timeout = TimeSpan.FromSeconds(5);
Exception pingexception = null;
System.Threading.Thread ping = new System.Threading.Thread(
delegate()
{
try
{
// just call the ping function
// use svr.Ping() in most cases
// PingFunc.Invoke is used in my case because I use
// reflection to determine if the Ping function is
// defined in type T
PingFunc.Invoke(svr, null);
}
catch (Exception ex)
{
pingexception = ex;
}
}
);
ping.Start(); // start the ping thread.
if (ping.Join(timeout)) // wait for thread to return for the time specified by timeout
{
// if the ping thread returned and no exception was thrown, we know the connection is available
if (pingexception == null)
return true;
}
// if the ping thread times out... return false
return false;
}
Hopefully the comments explain what I do here, but I'll give you a breakdown of the whole function. If you're not interested, just skip down to where I explain the ping thread.
DebuggerHidden Attribute
I set the DebuggerHidder attribute because when debugging, exceptions can be thrown here constantly in the ping thread, and they are expected. It is easy enough to comment this out should debugging this function become necessary.
Why I use reflection and a generic type
The 'svr' parameter is expected to be a type with a Ping function. In my case, I have a few different remotable interfaces implemented on the server with a common Ping function. In this way, I can just call Ping(svr) without having to cast or specify a type (unless the remote object is instantiated as an 'object' locally). Basically, this is just for syntactical convenience.
The Ping Thread
You can use whatever logic you want to determine an acceptable timeout, in my case, 5 seconds is good. I create a TimeSpan 'timeout' with a value of 5 seconds, an Exception pingexception, and create a new thread that tries to call 'svr.Ping()', and sets 'pingexception' to whatever exception is thrown when calling 'svr.Ping()'.
Once I call 'ping.Start()', I immediately use the boolean method ping.Join(TimeSpan) to wait for the thread to return successfully, or move on if the thread doesn't return within the specified amount of time. However, if the thread finished executing but an exception was thrown, we still don't want Ping to return true because there was a problem communicating with the remote object. This is why I use the 'pingexception' to make sure that no exceptions occurred when calling svr.Ping(). If 'pingexception' is null at the end, then I know I'm safe to return true.
Oh and to answer the question you originally asked (....sometimes it blocks on a method called NegotiateStream.ProcessRead during the process, and I can't understand why...), I have never been able to figure out the timeout issues with .NET Remoting, so this method is what I've baked and cleaned up for our .NET Remoting needs.
I've used an improved version of this with generics:
internal static TResult GetRemoteProperty<T, TResult>(string Url, System.Linq.Expressions.Expression<Func<T, TResult>> expr)
{
T remoteObject = GetRemoteObject<T>(Url);
System.Exception remoteException = null;
TimeSpan timeout = TimeSpan.FromSeconds(5);
System.Threading.Tasks.Task<TResult> t = new System.Threading.Tasks.Task<TResult>(() =>
{
try
{
if (expr.Body is System.Linq.Expressions.MemberExpression)
{
System.Reflection.MemberInfo memberInfo = ((System.Linq.Expressions.MemberExpression)expr.Body).Member;
System.Reflection.PropertyInfo propInfo = memberInfo as System.Reflection.PropertyInfo;
if (propInfo != null)
return (TResult)propInfo.GetValue(remoteObject, null);
}
}
catch (Exception ex)
{
remoteException = ex;
}
return default(TResult);
});
t.Start();
if (t.Wait(timeout))
return t.Result;
throw new NotSupportedException();
}
internal static T GetRemoteObject<T>(string Url)
{
return (T)Activator.GetObject(typeof(T), Url);
}

How to in case of timeout to execute method again and again until it completes successfully?

I have asp.net application. All business logic in business layer.
Here is the example of the method
public void DoSomething()
{
PersonClass pc = new PersonClass();
pc.CreatePerson();
pc.AssignBasicTask();
pc.ChangePersonsStatus();
pc.CreateDefaultSettings();
}
what happens once in a while, one of the sub method can timeout, so as a result the process can be incompleted.
what I think in this case to make sure all steps completed properly is
public void DoSomething()
{
PersonClass pc = new PersonClass();
var error = null;
error = pc.CreatePerson();
if(error != timeout exception)
error = pc.AssignBasicTask();
else
return to step above
if(error != timeout exception)
error = pc.ChangePersonsStatus();
else
return to step above
if(error != timeout exception)
error = pc.CreateDefaultSettings();
else
return to step above
}
but it's just an idea, more then sure it's a proper way how to handle this.
Of course, this can be done more or less elegantly, with different options for timing out or giving up - but an easy way to achieve what you want, would be to define a retry method which keeps retrying an action until it succeeds:
public static class RetryUtility
{
public T RetryUntilSuccess<T>(Func<T> action)
{
while(true)
{
try
{
return action();
}
catch
{
// Swallowing exceptions is BAD, BAD, BAD. You should AT LEAST log it.
}
}
}
public void RetryUntilSuccess(Action action)
{
// Trick to allow a void method being passed in without duplicating the implementation.
RetryUntilSuccess(() => { action(); return true; });
}
}
Then do
RetryUtility.RetryUntilSuccess(() => pc.CreatePerson());
RetryUtility.RetryUntilSuccess(() => pc.AssignBasicTask());
RetryUtility.RetryUntilSuccess(() => pc.ChangePersonsStatus());
RetryUtility.RetryUntilSuccess(() => pc.CreateDefaultSettings());
I must urge you to think about what to do if the method keeps failing, you could be creating an infinite loop - perhaps it should give up after N retries or back off with exponentially raising retry time - you will need to define that, since we cannot know enough about your problem domain to decide that.
You have it pretty close to correct in your psuedo-code, and there a lot of ways to do this, but here is how I would do it:
PersonClass pc = new PersonClass();
while(true)
if(pc.CreatePerson())
break;
while(true)
if(pc.AssignBasicTask())
break;
This assumes that your methods return true to indicate success, false to indicate a timeoiut failure (and probably an exception for any other kind of failure). And while I didn't do it here, I would strongly recommend some sort of try counting to make sure it doesn't just loop forever and ever.
Use a TransactionScope for to make sure everything is executed as a unit. More info here: Implementing an Implicit Transaction using Transaction Scope
You should never retry a timed out operation infinitely, you may end up hanging the server or with an infinite loop or both. There should always be a threshold of how many retries is acceptable to attempt before quitting.
Sample:
using(TransactionScope scope = new TransactionScope())
{
try
{
// Your code here
// If no errors were thrown commit your transaction
scope.Complete();
}
catch
{
// Some error handling
}
}

Additional try statement in catch statement - code smell?

Situation:
My application need to process the first step in the business rules (the initial try-catch statement). If an certain error occurs when the process calls the helper method during the step, I need to switch to a second process in the catch statement. The back up process uses the same helper method. If an same error occurs during the second process, I need to stop the entire process and throw the exception.
Implementation:
I was going to insert another try-catch statement into the catch statement of the first try-catch statement.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
HelperMethod(s1);
}
catch(Exception e1)
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
//try catch statement for second process.
try
{
HelperMethod(s2);
}
catch(Exception e2)
{
throw e2;
}
}
What would be the correct design pattern to avoid code smells in this implementation?
I caused some confusion and left out that when the first process fails and switches to the second process, it will send different information to the helper method. I have updated the scenario to reflect the entire process.
If the HelperMethod needs a second try, there is nothing directly wrong with this, but your code in the catch tries to do way too much, and it destroys the stacktrace from e2.
You only need:
try
{
//call helper method
HelperMethod();
}
catch(Exception e1)
{
// maybe log e1, it is getting lost here
HelperMethod();
}
I wouldn't say it is bad, although I'd almost certainly refactor the second block of code into a second method, so keep it comprehensible. And probably catch something more specific than Exception. A second try is sometimes necessary, especially for things like Dispose() implementations that might themselves throw (WCF, I'm looking at you).
The general idea putting a try-catch inside the catch of a parent try-catch doesn't seem like a code-smell to me. I can think of other legitimate reasons for doing this - for instance, when cleaning up an operation that failed where you do not want to ever throw another error (such as if the clean-up operation also fails). Your implementation, however, raises two questions for me: 1) Wim's comment, and 2) do you really want to entirely disregard why the operation originally failed (the e1 Exception)? Whether the second process succeeds or fails, your code does nothing with the original exception.
Generally speaking, this isn't a problem, and it isn't a code smell that I know of.
With that said, you may want to look at handling the error within your first helper method instead of just throwing it (and, thus, handling the call to the second helper method in there). That's only if it makes sense, but it is a possible change.
Yes, a more general pattern is have the basic method include an overload that accepts an int attempt parameter, and then conditionally call itself recursively.
private void MyMethod (parameterList)
{ MyMethod(ParameterList, 0)l }
private void MyMethod(ParameterList, int attempt)
{
try { HelperMethod(); }
catch(SomeSpecificException)
{
if (attempt < MAXATTEMPTS)
MyMethod(ParameterList, ++attempt);
else throw;
}
}
It shouldn't be that bad. Just document clearly why you're doing it, and most DEFINITELY try catching a more specific Exception type.
If you need some retry mechanism, which it looks like, you may want to explore different techniques, looping with delays etc.
It would be a little clearer if you called a different function in the catch so that a reader doesn't think you're just retrying the same function, as is, over again. If there's state happening that's not being shown in your example, you should document it carefully, at a minimum.
You also shouldn't throw e2; like that: you should simply throw; if you're going to work with the exception you caught at all. If not, you shouldn't try/catch.
Where you do not reference e1, you should simply catch (Exception) or better still catch (YourSpecificException)
If you're doing this to try and recover from some sort of transient error, then you need to be careful about how you implement this.
For example, in an environment where you're using SQL Server Mirroring, it's possible that the server you're connected to may stop being the master mid-connection.
In that scenario, it may be valid for your application to try and reconnect, and re-execute any statements on the new master - rather than sending an error back to the caller immediately.
You need to be careful to ensure that the methods you're calling don't have their own automatic retry mechanism, and that your callers are aware there is an automatic retry built into your method. Failing to ensure this can result in scenarios where you cause a flood of retry attempts, overloading shared resources (such as Database servers).
You should also ensure you're catching exceptions specific to the transient error you're trying to retry. So, in the example I gave, SqlException, and then examining to see if the error was that the SQL connection failed because the host was no longer the master.
If you need to retry more than once, consider placing an 'automatic backoff' retry delay - the first failure is retried immediately, the second after a delay of (say) 1 second, then doubled up to a maximum of (say) 90 seconds. This should help prevent overloading resources.
I would also suggest restructuring your method so that you don't have an inner-try/catch.
For example:
bool helper_success = false;
bool automatic_retry = false;
//run initial process
try
{
//call helper method
HelperMethod();
helper_success = true;
}
catch(Exception e)
{
// check if e is a transient exception. If so, set automatic_retry = true
}
if (automatic_retry)
{ //try catch statement for second process.
try
{
HelperMethod();
}
catch(Exception e)
{
throw;
}
}
Here's another pattern:
// set up state for first attempt
if(!HelperMethod(false)) {
// set up state for second attempt
HelperMethod(true);
// no need to try catch since you're just throwing anyway
}
Here, HelperMethod is
bool HelperMethod(bool throwOnFailure)
and the return value indicates whether or not success occurred (i.e., false indicates failure and true indicates success). You could also do:
// could wrap in try/catch
HelperMethod(2, stateChanger);
where HelperMethod is
void HelperMethod(int numberOfTries, StateChanger[] stateChanger)
where numberOfTries indicates the number of times to try before throwing an exception and StateChanger[] is an array of delegates that will change the state for you between calls (i.e., stateChanger[0] is called before the first attempt, stateChanger[1] is called before the second attempt, etc.)
This last option indicates that you might have a smelly setup though. It looks like the class that is encapsulating this process is responsible for both keeping track of state (which employee to look up) as well as looking up the employee (HelperMethod). By SRP, these should be separate.
Of course, you need to a catch a more specific exception than you currently are (don't catch the base class Exception!) and you should just throw instead of throw e if you need to rethrow the exception after logging, cleanup, etc.
You could emulate C#'s TryParse method signatures:
class Program
{
static void Main(string[] args)
{
Exception ex;
Console.WriteLine("trying 'ex'");
if (TryHelper("ex", out ex))
{
Console.WriteLine("'ex' worked");
}
else
{
Console.WriteLine("'ex' failed: " + ex.Message);
Console.WriteLine("trying 'test'");
if (TryHelper("test", out ex))
{
Console.WriteLine("'test' worked");
}
else
{
Console.WriteLine("'test' failed: " + ex.Message);
throw ex;
}
}
}
private static bool TryHelper(string s, out Exception result)
{
try
{
HelperMethod(s);
result = null;
return true;
}
catch (Exception ex)
{
// log here to preserve stack trace
result = ex;
return false;
}
}
private static void HelperMethod(string s)
{
if (s.Equals("ex"))
{
throw new Exception("s can be anything except 'ex'");
}
}
}
Another way is to flatten the try/catch blocks, useful if you're using some exception-happy API:
public void Foo()
{
try
{
HelperMethod("value 1");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
try
{
HelperMethod("value 2");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
// ... more here if needed
}
An option for retry (that most people will probably flame) would be to use a goto. C# doesn't have filtered exceptions but this could be used in a similar manner.
const int MAX_RETRY = 3;
public static void DoWork()
{
//Do Something
}
public static void DoWorkWithRetry()
{
var #try = 0;
retry:
try
{
DoWork();
}
catch (Exception)
{
#try++;
if (#try < MAX_RETRY)
goto retry;
throw;
}
}
In this case you know this "exception" probably will happen so I would prefer a simple approach an leave exceptions for the unknown events.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
if(!HelperMethod(s1))
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
if(!HelperMethod(s2))
{
return ErrorOfSomeKind;
}
}
return Ok;
}
catch(ApplicationException ex)
{
throw;
}
I know that I've done the above nested try catch recently to handle decoding data where two third party libraries throw exceptions on failure to decode (Try json decode, then try base64 decode), but my preference is to have functions return a value which can be checked.
I generally only use the throwing of exceptions to exit early and notify something up the chain about the error if it's fatal to the process.
If a function is unable to provide a meaningful response, that is not typically a fatal problem (Unlike bad input data).
It seems like the main risk in nested try catch is that you also end up catching all the other (maybe important) exceptions that might occur.

Why use try {} finally {} with an empty try block?

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.

Categories

Resources