The main thing wrong with the code is that object.ReferenceEquals(a,b) will ALWAYS return true because it’s comapring structs, which are value types. Value types are passed by value, not reference, so every instance is different.
Â
The main thing wrong with the code is that object.ReferenceEquals(a,b) will ALWAYS return true because it’s comapring structs, which are value types. Value types are passed by value, not reference, so every instance is different.
Â
In .Net you have the option of Thread.Suspend() and Thread.Abort(), but under normal circumstances these are horrible options to use because they’re likely to create locking problems (i.e., the thread has a locks on resource that other threads need).
A far better way is to signal to the thread that it should pause and wait for a signal to continue. Sometimes it can be as simple as setting a boolean value where both threads can see it. Or you could wrap the boolean value in a property and protect it with a lock, but this is probably overkill for most applications.
To pause a thread safely requires you to use a blocking signal mechanism and .Net has ManualResetEvent for just this purpose.
You could then have some C# code like this:
ManualResetEvent pauseEvent = new ManualResetEvent();
//Thread A (Controlling thread)
void OnPause()
{
pauseEvent.Reset();
}void OnStart()
{
pauseEvent.Set();
}//Thread B (the one to pause)
void ThreadFunction()
{
while(doWork == true)
{
//do work
…
…//wait until event is set
pauseEvent.WaitOne();
}
}
This way, you can safely pause work and continue it at a later time, safely avoiding the possibility of deadlocks*.
* Actually, it’s still possible to create a resource locking problem–make sure you release any shared resource locks before pausing.
What is wrong with the following code?Â
struct Foo {
   public int id;
   public string value;
   public static readonly Foo Empty = new Foo(“”);   public Foo(string val)
   {
        this.value = val;
        this.id = -1;
    }};
and elsewhere…
Foo m = new Foo(“Something”);Â
if (object.ReferenceEquals(m, Foo.Empty))
{
   …//do something
} else
{
…
}
Â
A useful attribute in .Net is Obselete. When you mark a method with this the compiler will flag any line that accesses the method (or property, or whatever) with a warning (error is optional).
I recently used it for a framework that sits between a database and applications–I wanted to faithfully reflect the database design (since it’s too dangerous to change that), but I want to be warned away from using cetain functionality unless necessary.
Example:
[Obsolete(“You shouldn’t be calling this method!”)]
public void MyMethod()
{
…
}Main()
{
   this.MyMethod();
}
The compiler will then say:
warning CS0618: [class…].MyMethod’ is obsolete: ‘You shouldn’t be calling this method!’
The “as” keyword is very useful in managed code because it solves a very common problem.
Suppose you have this:
object o;
…
…
string s = (string)o;
but what if o is null? Then you will get a NullReferenceException. Sometimes this is ok, but often if o is null, you want s to be null as well.
Enter ‘as’. as is like a typecast that will return null if needed.
Your code would then be:
string s = o as string;
This is why you can’t use ‘as’ with value types (int, bool, structs, etc.)–they can’t take on the value of null in the first place. With .Net 2.0, however, the rules change…
I have a service that’s absolutely critical to business functions that relies on both Exchange and SQL Server. The problem is that the service’s existing code has a number of places where a failure to connect to the database will result in a dummy, “bad” value being returned from the data access layer. The business layer doesn’t know if the bad values came from bad input data or no database connection, and it assumes the former. This leads to data loss for the customer.
I see three possible solutions for this:
I went with 3 because it is also conceptually closer to what should happen. If the database is unavailable, the service can’t possibly do any meaningful work so it should just stop until the database comes back up.
The code to detect a database disconnect is very simple:
static bool IsDatabaseAlive()
{
   SqlConnection connection = null;
   try
   {
        string strConnection = ConfigurationSettings.AppSettings[“ConnectionString”];
        using(connection = new SqlConnection(strConnection))
        {
             connection.Open();
             return (connection.State != ConnectionState.Open);
         }
    }
    catch
    {
         return false;
    }
}
Â
I run this code before running through the processing loops. If the database is alive I go ahead and process. Â
I needed a simple array of strings today, and I needed to be able to return it via a property. I could use a simple array, but that has some significant drawbacks. I could use an ArrayList, but the indexer returns an object, which would force the application to always cast it. I decided to derive a class from ArrayList and change the indexer. Something like this would work:
public class EmailList : System.Collections.ArrayList
{
public void Add(string email) { base.Add(email); }
public new string this[int index] {
   get { return (string)base[index]; }
   set { base[index] = value; }
 }
}
Notice the “new” keyword for the indexer. This tells the compiler to override the indexer provided by the base class. Now, whatever classes use this class can get a string back from the array list without having to cast it every time. There are other things you can do to customize this collection, but it’s a good start.
Does it strike anyone else as ironic that ArgumentException and ArgumentNullException have mismatched argument ordering? The parameter name is first for the null version, but second for the other one. Uggh… this makes it awkward to remember if you use both. ArgumentOutOfRangeException follows the example of ArgumentNullException.
I can see no obvious reason for the discrepancy. In all three cases, the constructors are exactly the same. In fact, MSDN explicitly says that the behavior is the same.
I read Rico Mariani’s latest quiz, and decided to check out the results for myself in BRayTracer.
I already have some simple performance benchmark tests in my NUnit tests, so I ran some before and after. I changed only the ArrayList’s used in the scene object to hold shapes, materials, and lights.
Before:
25.197 opaque spheres/sec (time: 3.969 )
After:
31.841 opaque spheres/sec (time: 3.141 )
Pretty impressive savings with minimal work! Almost a full second! In an enormous scene, that will add up to a LOT of time saved. I still have to change the implementation for polygons and polygonal meshes–this will greatly speed up those operations, which are currently fairly slow. In fact, the way I have polygonal meshes written at the moment, they’re nearly impossible to render in a decent amount of time.
More exciting things coming to BRayTracer soon…
Over the summer I’m taking a class called Programming Languages and Security. This is the first time I’ve delved into security at this level before. It’s a seminar style, which means lots of paper reading, and I am going to give two presentations.
My first presentation was this past Thursday. I spoke about typed assembly language and security automata. It was absolutely fascinating, ignoring the formality of proofs, and all the mathematical notations.
The two papers I discussed were:
The TALx86 begins by describing many shortcomings of the Java Virtual Machine Language (bytecode), including such things as:
My immediate thought on reading this was, “Hey! .Net addresses each and every single one of these points!”
It also seems that many of the experimental features present in such early research, such as TALx86, has ended up in .Net and compilers these days. Type safety is being pushed lower and lower. Security policies are being implemented into frameworks, operating systems and compilers, and there are other tools that analyze your code for adherence to security best practices.
On platforms such as .Net, type safety is more important because you can have modules written in VB.Net interacting with objects written in C++ or Python, for example. Those languages don’t know about each other’s types, but at the MSIL level you can ensure safety.
If you’d like, a copy of the presentation is available.