2007-06-28

Documentator Macros version 2.5.1.0 released

For you who are using Visual Studio 2005, the DocumentatorMacros is released in version 2.5.1.
For more information about the macros, see
http://www.codeproject.com/csharp/documentatormacros.asp

The major reason for a new release is the support for restoring shortcuts after Resharper 3.0 has been installed. Apart from that, the new release only contains minor bugfixes and changes. See the included documentation for more information.

Since I just posted the update to codeproject, the latest version is not available there yet.
So in the meantime you can download it from here.

2007-06-20

AdobeUpdater.exe hangs and cannot be killed

Today I have been experiencing a problem with adobes AdobeUpdater.exe. It takes 100% cpu usage and cannot be killed. The only way to get rid of it is to reboot and even that don't always work. Sometimes a hard reset (a.k.a. da button) is the only effective solution.

Searched a bit and found several others to have the same problem.

Suggested solutions:
  1. Rename
    c:\program files\Adobe\Updater5\AdobeUpdater.exe
    to (for example)
    c:\program files\Adobe\Updater5\AdobeUpdater.exe.old
    This will prevent the AdobeUpdater.exe from running.
    ( tip from Nish Vamadevans blog)

  2. Uninstall Adobe acrobat reader and use another software (like Foxit)

  3. Create an own Adobe installation package using the Adobe customization wizard 8 where you don't include the AdobeUpdater. See Aaron Parker's stealthpuppy.com
Hopefully Adobe will release a patch for this, but so far (version 8.1) the issue has not been fixed.

P.S. I went for solution 2, since I already had foxit installed. D.S.

2007-06-12

Animals and Baboons explained

I have been doing some research on the Animal/Baboon generic issue.
First I posted a feedback on the Microsoft connect site and got some answers. This issue is referred as covariance.
Covariance, in a mathematical definition, refers to how much two random variables varies together.
Covariance, in this aspect, refers to on how you can assign two variables/types to each other. Normally (without covariance) we can only assign objects to variables that are part of their inheritance chain or cast up the inheritance chain.
For instance

AccessViolationException ax = new AccessViolationException();
//assign down the inheritance chain
Exception ex = ax;
//cast up the inheritance chain
ax = ex as AccessViolationException;
We can also cast/assign to other types, but then it is up to the object to handle the cast/assignment by implementing the explicit or implicit operators for each type that it should support.

When it comes to covariance, this is already implemented in the CLR and C# (like Java) uses covariance for its support on Arrays.
To illustrate this we can use our Animal/Baboon/List<T> example.
List<Animal> myAnimalList;
List<Baboon> myBaboonList;
myAnimalList = myBaboonList; //gives a compiler error
The code above gererated a compiler error since we cannot convert the Baboon List to an Animal List. Baboon inherits Animal but List<Baboon> does not inherit List<Animal> and thus cannot be assigned to each others. But what happens if we do the same with arrays?
Baboon[] myBaboons = null;
Animal[] myAnimals;
myAnimals = myBaboons; //this works!?
How is this possible? Baboon[] does not inherit Animal[]. All arrays inherits System.Array.
This is because System.Array uses Covariance in the CLR to allow such a structure. Observe that the opposite is not possible
myBaboons = myAnimals; //gives a compiler error

This is called Contravariant and is not used by Arrays.

For now there is no other object or class that uses co/contra-variance in C# but since the feature is included in the CLI, you could build an own C# compiler that supports it.
Microsoft will not include the support in C# v3 but according to Mads Torgersen they are "actively looking at supporting it in the next version of the language after that".
If you would like more reading on the subject, I can recommend the following sources that have given me much input.

2007-06-08

Why I ever left Unix (swedish only, sorry)

När man kör sin playlist på shuffle så vet man aldrig var man får tag på, speciellt om man aldrig rensar bland sina filer.
Lyssna på denna för att få svar på frågan...

Download

2007-06-07

Are Baboons Animals (in a generic sense)

I was writing a generic class in C# today and generics is great and all that, but it's not quite complete in it's design (not in todays target anyway). I will give you an example.

Say that you declare an Animal class


public class Animal {
public Animal(string division, string className,
string order, string family, string genus){}
}

And then we declare the Baboon...

public class Baboon : Animal {
public Baboon() :
base("Chordata","Mammalia","Primates",
"Cercopithecidae","Papio") {}
}

All is well, a standard object inheritance (even one with an anchor in the real world (oh yeah!), and a scientific twist (bring it on!))

Now we would like a generic collection for the animals that only can take animals.

public class BaseAnimalCollection<T> : List<T>
where T : Animal{}

Cool, now this type of collection can contain all sorts of animals and we could add methods common to all animal life, like... like... well, Clone and Exterminate are the first that comes to mind... (think I should read something more than scientific magazines to broaden my horizon?)

Anyway...
We start using the collection

BaseAnimalCollection<Animal> myAnimalCollection =
new BaseAnimalCollection<Animal>();

Here we can put som animals in...

We can also specify a collection that only can contains Baboons (if we want to use the common animal functionality that is provided with the collection (Clone and Exterminate ;)

BaseAnimalCollection<Baboon> myBaboonCollection =
new BaseAnimalCollection<Baboon>();

The strength with generics is that we can, with little effort (code), create a typed collection that behaves as a collection should and we don't need to fear any runtime nuisances since the type checking is done in compilation time.

So when I would like to create my best of animal collections (everyone has these nowadays) I just create a typed collection and add on...

BaseAnimalCollection<Animal> myBestAnimalCollection =
new BaseAnimalCollection<Animal>();
//add some animals
myBestAnimalCollection.Add(new Animal(
"Arthropoda", "Arachnida", "Acarina.Parasitiformes",
"Ixodoidea", "Amblyomma"));
//add a Baboon !!!
myBestAnimalCollection.Add(new Baboon());
//even add my own list of animals to the list.
myBestAnimalCollection.AddRange(myAnimalCollection);

So far all is good. Now I want to add my baboon list to the best of collection. Since Baboons are animals (and I have already added a Baboon to the list) this should be ok . So we add the code below.

myBestAnimalCollection.AddRange(myBaboonCollection);

Now we get two compilation errors...

The best overloaded method match for 'System.Collections.
Generic.List.AddRange(System.Collections.Generic.
IEnumerable)' has some invalid arguments

Argument '1': cannot convert from 'BaseAnimalCollection'
to 'System.Collections.Generic.IEnumerable'

Why is this? Why can't we convert from a collection of Baboons to a enumerable of animals? Aren't Baboons animals when it comes to Generics or what?

Give me your best shot.

Good luck!
/Dan

2007-06-05

Writing a resource manager for System.Transactions

Currently I'm developing a O/R mapper that needs a Resource Manager to keep track of the inner states of the objects that it maps when a transaction starts. To do this I want to create a ResourceManager that can participate in a transaction and be commited and rolled back in line with the other managers in the transaction. The ISinglePhaseNotification interface seemed to be a great interface to use.

I wrote a simple class that implemented the ISinglePhaseNotification interface and tried it. At first it seemed to work like a charm, but then I got these strange behaviors.
I wrote a little test that enlisted the resource manager in a transaction, and when the transaction was completed, checked the Commited flag (that I set when the IEnlistmentNotification.Commit has been finished).


MyResourceManager rm = new MyResourceManager();
using (TransactionScope s = new TransactionScope()) {
rm.Enlist();
s.Complete();
}
Assert.AreEqual(true, rm.Committed);

The problem is that the test don't always succeed. This seemed like a school example for a resource manager
  1. create one
  2. enlist into the transaction
  3. mark the transaction as complete
  4. end the transaction
  5. validate that the resource manager has been committed.
The error was more reliable when the commit took longer to execute (sleep a few seconds). It seems like when the TransactionScope is disposed, the transaction threads the calls to the resource managers and don't wait for them to finish before continuing.

This behavior has to work since after a transaction ends, I need to update/change the data of the objects in the system and they need to be available immediately after the TransactionScope has ended.
I hope this only is configuration issue and that I have missed some central issue regarding Resource managers and Transactions. Please enlighten me...

I post the complete test code below for you to use to reproduce the test. You'll see that the Assert will never work since the Commit will not be set at once but only after a small timeout (2 sec).

If I run the test with the Assert commented i will receive the following output.

TransactionScope BEGIN
IEnlistmentNotification.Prepare
IEnlistmentNotification.Commit BEGIN
TransactionScope END
IEnlistmentNotification.Commit END


And this illustrates the problem. The transaction scope is ended before the commit has been completely done.
Has someone some ideas?

Regards
/Dan


using System;
using System.Threading;
using System.Transactions;
using NUnit.Framework;

namespace OneProcess {
[TestFixture]
public class Test2 {
[Test]
public void OnlyLocalTest() {

MyResourceManager rm = new MyResourceManager();
Console.WriteLine("TransactionScope BEGIN");
using (TransactionScope s = new TransactionScope()) {
rm.Enlist();
s.Complete();
}
Console.WriteLine("TransactionScope END");
Assert.AreEqual(true, rm.Committed);
Thread.Sleep(3000);

}
public class MyResourceManager
: ISinglePhaseNotification {
public bool Committed = false;
public void Enlist() {
if (null != Transaction.Current) {
Transaction.Current.EnlistDurable(
Guid.NewGuid(), this,
EnlistmentOptions.EnlistDuringPrepareRequired);
}
}

void ISinglePhaseNotification.SinglePhaseCommit(
SinglePhaseEnlistment singlePhaseEnlistment) {
Console.WriteLine(
"ISinglePhaseNotification.SinglePhaseCommit");
Committed = true;
singlePhaseEnlistment.Committed();
}


void IEnlistmentNotification.Commit(Enlistment enlistment) {
Console.WriteLine(
"IEnlistmentNotification.Commit BEGIN");
Thread.Sleep(2000);
Committed = true;
enlistment.Done();
Console.WriteLine(
"IEnlistmentNotification.Commit END");
}

void IEnlistmentNotification.InDoubt(Enlistment enlistment) {
Console.WriteLine("IEnlistmentNotification.InDoubt");
enlistment.Done();
}

void IEnlistmentNotification.Prepare(
PreparingEnlistment preparingEnlistment) {
Console.WriteLine("IEnlistmentNotification.Prepare");
preparingEnlistment.Prepared();
}
void IEnlistmentNotification.Rollback(Enlistment enlistment) {
Console.WriteLine("IEnlistmentNotification.Rollback");
Thread.Sleep(2000);
enlistment.Done();
}
}
}
}