I have an InfoPath form which I need to conditionally disable it's OnChange events. Since it's not possible to bind the event handlers after the form has loaded, I'm forced to rely on a global counter which indicates whether an OnChange event should be executed. Inside each OnChange event, I check whether SuppressEventsCount == 0 before performing any actions. To suppress events during the execution of some function or another, I simply set SuppressEventsCount++, and -- again when the function exits. The biggest problem with doing this is that it's not exception safe. So I had the bright idea to wrap the SuppressEvents counter in a class which implements iDisposable
using(SuppressEvents s = new SuppressEvents()){
// OnChange events fired here are ignored
} // OnChange events enabled again
This is working, but it's still not as ideal as a c++ solution which doesn't require the use of the "using" directive at all.
Is there some way to either:
> C does not have RAII-like memory management in any way. C does not have memory management in any way period. The C standard library does. How you get to something with dynamic scoping like RAII in C is to use a different library for managing memory.
Resource Acquisition Is Initialization or RAII, is a C++ programming technique which binds the life cycle of a resource that must be acquired before use (allocated heap memory, thread of execution, open socket, open file, locked mutex, disk space, database connection—anything that exists in limited supply) to the ...
The key to RAII is the reliable and automatic execution of destructors. The compiler's job is two-fold: Generate destructor calls in the normal execution flow of the program. Generate code that will call the necessary destructors to be run in the case of an exception.
Smart pointers use RAII to hide the manipulation of pointers, which are a lower level than business code, so RAII helps respect levels of abstraction in that case too. This is true for resource management in general, including database connection.
No and no. using
is the closest you can get to RAII (more accurately, we are talking about the resource release that follows a RAII-idiom object being destructed).
To answer your points more directly:
IDisposable
(and by extension using
) was created exactly because there is no way to do that in .NET.using
is syntactic sugar that gets compiled as try
/finally
and only requires that the object is IDisposable
, so you cannot distinguish between usage inside a using
statement and out of it.In relation to question 2, it might be possible to get around it by providing a different interface to consumers of the code. Instead of providing a public class that implements IDisposable
, and hoping they wrap it in a using
, you could provide a static method that takes a function to execute in a "suppressed" context:
public static class EventSuppressor {
public void Suppress(Action action) {
using (var s = new SuppressActions()) {
action();
}
}
private class SuppressActions : IDisposable {
...
}
}
Then consumers can use this as follows:
EventSuppressor.Suppress(() => {
// OnChange events fired here are ignored
}) // OnChange events enabled again
Of course, you have to work out whether this design is appropriate, as this will result in extra function calls, compiler generated classes and closures etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With