Expose the fault IL feature #3240
Replies: 8 comments 2 replies
-
Related previous discussions: #434 and dotnet/roslyn#14831. Also, I think that when discussing a feature, it's important to understand what its use cases are, just saying they exist is not sufficient. So, what are the use cases? |
Beta Was this translation helpful? Give feedback.
-
The problem prompting this ticket for me was the necessity to rethrow often in catch handlers after returning types requiring disposal, but only if an exception was thrown. I had to rethrow exceptions in certain catch handlers, which lead to quite a lot of code bloat. The fault handler is perfect for such a scenario, as it allows you to not rethrow the exception and still have a handler which is called on exceptions. I'll put a code sample up as soon as I can. Another indicator that there are valid use cases for this is is the fact that fault handlers are already emitted when yielding in a using block. The idea as far as I can tell is to not dabble with the exception by rethrowing but simply disposing on an error. Finally is not an option there as it would dispose too early. |
Beta Was this translation helpful? Give feedback.
-
var disposable = new DisposableThing();
var success = false;
try
{
SomethingThatCouldThrow();
success = true;
return disposable;
}
finally
{
if (!success) disposable.Dispose();
} If this happens a lot, I use a helper class to implement this pattern with using var tempFile = OwnershipTracker.Create(new TempFile());
// Do stuff with the temporary file that involves reading from sources that may throw.
// E.g.:
using var file = File.Create(tempFile.OwnedInstance);
await stream.CopyToAsync(file, cancellationToken).ConfigureAwait(false);
return tempFile.ReleaseOwnership(); Implementation: https://gist.github.com/jnm2/2302a81f7b8797d9e59a84c69d1e12bf |
Beta Was this translation helpful? Give feedback.
-
@Mrnikbobjeff why is the fault so much better than try
{
/// do some wprk
}
catch
{
tran.Rollback();
throw;
} An with hypotetical fault try
{
/// do some wprk
}
fault
{
tran.Rollback();
} It does not look like a big improvement
An the use cases or even potential performance improvements are questionable for the general case. |
Beta Was this translation helpful? Give feedback.
-
This is definitely the cleanest possible alternative but still way worse than simply declaring a fault handler, as this basically emulates a fault handler without the ability to add catch handlers on a per case basis. @popcatalin81 is correct that this simple try block does not get better with a fault handler. Now consider a try block with several different catch handlers which may execute logic on an individual basis. Netiher answer does offer a solution here (Sure, you could pass in an action or something into the quoted answer but this would make the code even more convoluted). I will send my code sample as soon as I return from my vacation. |
Beta Was this translation helpful? Give feedback.
-
Couldn't you also do something like: var disposable = new DisposableThing();
try
{
try
{
Stuff...
}
catch (A a) { }
catch (B b) { }
return disposable;
}
catch
{
disposable.Dispose();
throw;
} Sure it's still uglier than a |
Beta Was this translation helpful? Give feedback.
-
I will quote from Bart de Smet's Blogpost on fault handlers(http://bartdesmet.net/blogs/bart/archive/2009/12/06/reader-challenge-fault-handlers-in-c.aspx , link insertion is broken in GitHub on mobile), he expressed some thoughts very concisely about the purpose of the fault handler: |
Beta Was this translation helpful? Give feedback.
-
MotivationThere are two downsides I'm aware of with the obvious contender,
WorkaroundsIf you care about these downsides in your own code, you can use var disposableThing = ...;
var forcedSuccessFlag = false;
try
{
// ...
var forcedVariable = new ThingThatMightThrow(disposableThing);
forcedSuccessFlag = true;
return forcedVariable;
}
finally
{
if (!forcedSuccessFlag)
{
// Whatever cleanup, in case we don't actually return
disposableThing.Dispose();
}
} I also saw an IIFE stuffed into AlternativesDebuggers could gain a new setting so that they only stop on Further notesAs long as you use
Difficulty
In order to allow ConclusionAs much as I love the idea of exposing a native IL capability to C#, the motivation feels pretty thin to me. There are a couple of workarounds to choose from, one of which is easy to read and write, |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In the IL standard we have the fault exception handling mechanism outlined. It is not currently available in C#, even though there are use cases for it. I would love to have language support for this to not have to fall back to IL weaving.
For details see II.19.6 Fault handlers
Beta Was this translation helpful? Give feedback.
All reactions