I'm pretty old. I've been there and seen it and banged my head about it many times.
I was at a conference in Hursley Park where the IBM boys were telling us how wonderful this brand new Java language was, only someone asked ... why isn't there a destructor for these objects. He didn't mean the thing we know as a destructor in C++, but there was no finaliser either (or it had finalisers but they basically didn't work). This is way back, and we decided Java was a bit of a toy language at that point.
now they added Finalisers to the language spec and Java saw some adoption.
Of course, later everyone was told not to put finalisers on their objects because it slowed the GC down tremendously. (as it had to not only lock the heap but move the to-be-finalised objects to a temp area, as these methods could not be called as the GC has paused the app from running. Instead they would be called immediately before the next GC cycle)(and worse, sometimes the finaliser would never get called at all when the app was shutting down. Imagine not having your file handle closed, ever)
Then we had C#, and I remember the discussion forum on MSDN where we were told how wonderful this new C# language was. Someone asked why there was no deterministic finalisation and the MS boys told us how we didn't need such things, then told us we needed to change our way of designing apps, then told us how amazing GC was and how all our old apps were rubbish and never worked because of all the circular references. Then they caved in to pressure and told us they'd added this IDispose pattern to the spec that we could use. I thought it was pretty much back to manual memory management for us in C# apps at that point.
Of course, the MS boys later discovered that all they'd told us was... well, they made IDispose a bit more than just a standard interface, and later added the using statement. W00t! They realised that deterministic finalisation was something missing from the language after all. Of course, you still have to remember to put it in everywhere, so its still a bit manual, but it's better.
So why did they do it when they could have had using-style semantics automatically placed on each scope block from the start? Probably efficiency, but I like to think that they just didn't realise. Just like eventually they realised you still need smart pointers in .NET (google SafeHandle) they thought that the GC really would solve all problems. They forgot that an object is more than just memory and that GC is primarily designed to handle memory management. they got caught up in the idea that the GC would handle this, and forgot that you put other stuff in there, an object isn't just a blob of memory that doesn't matter if you don't delete it for a while.
But I also think that the lack of a finalise method in the original Java had a bit more to it - that the objects you created were all about memory, and if you wanted to delete something else (like a DB handle or a socket or whatever) then you were expected to do it manually.
Remember Java was designed for embedded environments where people were used to writing C code with lots of manual allocations, so not having automatic free wasn't much of a problem - they never did it before, so why would you need it in Java? The issue wasn't anything to do with threads, or stack/heap, it was probably just there to make memory allocation (and therefore de-alloc) a bit easier. In all, the try/finally statement is probably a better place to handle non-memory resources.
So IMHO, the way .NET simply copied Java's biggest flaw is its biggest weakness. .NET should have been a better C++, not a better Java.