Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
688 views
in Technique[技术] by (71.8m points)

vb.net - Why doesn't C# have support for first pass exception filtering?

Note: this is not a duplicate of Jeff's question.

That question asked "Is an equivalent?" I know there isn't, and I want to know why!

The reason I ask is that I've only just become clear on how important it is, and the conclusion seems very strange to me.

The Exception Handling block of Microsoft's Enterprise Library advises us to use this pattern:

catch (Exception x)
{
    if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
        throw;

    // recover from x somehow
}

The policy is defined in an XML file, so that means that if a customer has an issue, we can modify the policy to assist with tracking down (or perhaps papering over) the problem to give them a fast resolution until we deal with it properly - which may involve arguing with 3rd parties, about whose fault it all is.

This is basically an acknowledgement of the simple fact that in real applications the number of exception types and their "recoverability" status is practically impossible to manage without a facility like this.

Meanwhile, the CLR team at MS says this is not an option, and it turns out those guys know what they're talking about! The problem is that right before the catch block runs, any finally blocks nested inside the try block will be executed. So those finally blocks may do any of the following:

  • Harmlessly modify the program state (phew, lucky).
  • Trash something important in the customer's data, because the program state is screwed up to an unknown degree.
  • Disguise or destroy important evidence that we need to diagnose an issue - especially if we're talking about calls into native code.
  • Throw another exception, adding to the general confusion and misery.

Note that the using statement and C++/CLI destructors are built on try/finally, so they're affected too.

So clearly the catch/throw pattern for filtering exceptions is no good. What is actually needed is a way to filter exceptions, via a policy, without actually catching them and so triggering the execution of finally blocks, unless we find a policy that tells us the exception is safe to recover from.

The CLR team blogged about this recently:

The outcome is that we have to write a helper function in VB.NET to allow us to access this vital capability from C#. The big clue that there is a problem is that there is code in the BCL that does this. Lots of people have blogged about doing it, but they rarely if ever mention the thing about try/finally blocks, which is the killer.

What I would like to know is:

  • Are there any public statements or direct emails people have received from the C# team on this subject?
  • Are there any existing Microsoft Connect suggestions asking for this? I've heard rumours of them but none of the likely keywords turned up anything.

Update: as noted above, I have already searched on Microsoft Connect without finding anything. I have also (unsurprisingly) Googled. I've only found people explaining why they need this feature, or pointing out the advantages of it in VB.NET, or fruitlessly hoping that it will be added in a future version of C#, or working around it, And plenty of misleading advice. But no statement on the rationale for omitting it from all current versions of C#. And the reason I'm asking about existing Connect issues is so that (a) I don't create an unnecessary duplicate and (b) I can tell interested people if I have to create one.

Update 2: Found an interesting old blog post from Eric Gunnerson, formerly of the C# team:

"Yes, being able to put a condition on a catch is somewhat more convenient than having to write the test yourself, but it doesn't really enable you to do anything new."

That was the same assumption I had until it was properly explained to me!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As to any existing connect bugs. The following issue deals with exception fliters. The user did not explicitly state they wanted them be an actual filter in the sense of when they execute but IMHO it's implied by the logic.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=401668

Besides that issue though, there are no issues I can find or know of that are related to what you are looking for. I think it would do good to have a separate issue which explicitly calls out the want for VB.Net style exception filters.

I wouldn't worry too much about introducing a duplicate question if you've done a bit of due diligence looking for an existing one. If there is a dupe, Mads will dupe it accordingly and link you to the main request.

As for the part of getting an official response from the C# team, you will likely get that when you either 1) file a connect bug or 2) get duped against the main bug. I really doubt there is an official reason / justification out there right now.

Here's my speculation on the issue: My guess is that this feature simply wasn't on the original C# 1.0 feature set and since that time there hasn't been enough demand to make it into the language. The C# and VB team spend an unbelievable amount of time ranking language features at the start of every ship cycle. We have to make some very difficult cuts at times. Without sufficient demand there is very little chance a feature will make it into the language.

Up until recently I bet you would be hard pressed to find 1 out of 10 people who understood the difference between VB.Net's Try/When and just using a plain old if statement in a C# catch block. It seems to be a bit more on peoples minds lately so maybe it will make it into a future version of the langauge.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...