Groups | Blog | Home
all groups > dotnet framework > march 2008 >

dotnet framework : Anyone from Microsoft confirm this bug or explain this as feature


Aamir Mahmood
3/20/2008 11:54:18 PM
I have posted this issue earlier on
microsoft.public.dotnet.languages.csharp, but nobody replied to that.

Consider following code:

--------------------------------------------------------------------------------

private void button1_Click(object sender, EventArgs e) {
using (System.Transactions.TransactionScope tx = new TransactionScope())
{
System.Transactions.Transaction.Current.TransactionCompleted += new
TransactionCompletedEventHandler(Current_TransactionCompleted);

System.Console.WriteLine(System.Threading.Thread.CurrentThread.GetHashCode());
// prints 4, could be different on your machine
throw new Exception();

tx.Commit();
}
}

private void Current_TransactionCompleted(object sender,
TransactionEventArgs e) {
System.Console.WriteLine(System.Threading.Thread.CurrentThread.GetHashCode());
// prints 6, could be different on your machine
}

--------------------------------------------------------------------------------

The problem is the output, first it outputs 4, and it ouputs 6 (it can be a
different output on your machine).

I have various fields with [ThreadStatic] attribute. Since the
TransactionCompleted is coming on a different thread, it is making all those
[ThreadStatic] fields useless.
This is driving me crazy.

The event MUST be fired on the same thread that created TransactionScope and
subscribed this event.
But the Microsoft implemented in a way, that the initial thread is stopped
and a different thread is used to fire the event (WHY???). After the event
handler function finishes, application continues with the original thread.
WHY EVENT IS FIRED ON A DIFFERENT THREAD? I have [ThreadStatic] members
which I cannot use.
I have cleanup routines which were tied to that specific transactions
created for that specific thread.

Since this is not explained in any documentation, I think it is a bug.

Thanks.

AM.

Jon Skeet [C# MVP]
3/21/2008 8:40:47 AM
[quoted text, click to view]

<snip>

[quoted text, click to view]

Then you've got a design issue - it doesn't mean it's a bug.

[quoted text, click to view]

Well, it must for your code to work. I can't immediately see anything
in the documentation suggesting that that should happen though.

[quoted text, click to view]

Where is the guarantee to that it *will* occur in the same thread? If
there's no guarantee, you're relying on unspecified behaviour, which
you assumed would be the behaviour you wanted.

What would you expect to happen if you'd called BeginCommit from a
thread which wasn't running a message pump? How would you expect it to
marshall back to that thread?

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
Cowboy (Gregory A. Beamer)
3/21/2008 11:54:25 AM
I was not going to add anything here, as Jon has already provided a long
answer, but it started nagging on me, so I apologize, in advance.

First, let's understand bug and design flaw. Suppose I create a library that
creates a binary array out of a string. As I am working with English only, I
design this to return a single byte per character in the string. You,
working in another language, find that it is not giving you enough fidelity
to reproduce your string on the other end. So you call and say I have a bug.

My library does what I said it would do, so it is not a bug. If my library
turned the word fudge into the binary representation of turds, it would be a
bug, as it is not working as I stated it would work.

It could, however, be a design flaw, as it only works with ASCII values. The
question of whether or not it is a design flaw depends on stated intent. For
example, "creates a binary representation of an ASCII string" would not
indicate a design flaw, while "creates a binary representation of any
string" would.

-----------

Next, I see the statement
[quoted text, click to view]

So, you have a cleanup dependent not ONLY on the transaction, but on the
particular thread. This means your cleanup is actually work that is part of
the transaction, as it has a very tightly coupled dependency on more than
the work being done, but the actual manner in which it is completed. In
other words, the TransactionScope is not really what you are concerned with,
but the thread created to complete the TransactionScope.

If you ask me, it is a design flaw. It might be Microsoft's design flaw, as
they have not included a way to create a transaction for a transaction and
its cleanup. But, as you have the dependency, I would also argue that you
have a design flaw in your own code, as the TransactionScope is acting
exactly as published.

Let's, however, focus on it being a bug that Microsoft needs to fix. If so,
it will likely take weeks, at minimum, before we see a patch of any sort,
and months before a fully regression tested patch. Can you wait this long
before you fix the problem? If yes, then get on connect and log the bug. If
not, I would find a way to eliminate the thread dependency in your code. At
this point, working code is probably better than being right.

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my blog
http://gregorybeamer.spaces.live.com/lists/feed.rss

or just read it:
http://gregorybeamer.spaces.live.com/

*************************************************
| Think outside the box!
|
*************************************************
[quoted text, click to view]

AddThis Social Bookmark Button