Managing data within events A and B, when event C fires

K

kirk

I have three events, using event handler methods as depicted below.
Two of those event handler methods need to reset specific data
whenever the other event left fires. I wasn't sure how to properly
implement that, is there a better way than using state management
variables for each timer as i'm doing in the outline below?



private string szProperty1 = null;
// updated by class consumer
public string Property1
{
get { return this.szProperty1; }
set { this.szProperty1 = value; }
}

// state management
private string szProperty1Last1 = null;
private string szProperty1Last2 = null;
private string szProperty1Last3 = null;

private string szProperty2 = null;
private string szProperty3 = null;



[interval: 100ms]
private void EventHandlerMethod1
{
// exit if szProperty1 == null or no event subscriptions
// if szPropertyLast1 != szProperty1, set szPropertyLast1 =
szProperty1, fire event
}

[interval: 100ms]
private void EventHandlerMethod2
{
// exit if szProperty1 == null or no event subscriptions
// if szPropertyLast2 != szProperty1, set szPropertyLast2 =
szProperty1, reset szProperty2, fire event
}

[interval: 500ms]
private void EventHandlerMethod3
{
// exit if szProperty1 == null or no event subscriptions
// if szPropertyLast3 != szProperty1, set szPropertyLast3 =
szProperty1, reset szProperty3, fire event
}
 
P

Pavel Minaev

I have three events, using event handler methods as depicted below.
Two of those event handler methods need to reset specific data
whenever the other event left fires.  I wasn't sure how to properly
implement that, is there a better way than using state management
variables for each timer as i'm doing in the outline below?

private string szProperty1 = null;
// updated by class consumer
public string Property1
{
   get { return this.szProperty1; }
   set { this.szProperty1 = value; }

}

// state management
private string szProperty1Last1 = null;
private string szProperty1Last2 = null;
private string szProperty1Last3 = null;

private string szProperty2 = null;
private string szProperty3 = null;

[interval: 100ms]
private void EventHandlerMethod1
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast1 != szProperty1, set szPropertyLast1 =
szProperty1, fire event

}

[interval: 100ms]
private void EventHandlerMethod2
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast2 != szProperty1, set szPropertyLast2 =
szProperty1, reset szProperty2, fire event

}

[interval: 500ms]
private void EventHandlerMethod3
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast3 != szProperty1, set szPropertyLast3 =
szProperty1, reset szProperty3, fire event



}

Do you really need to do those resets in the event handlers? Couldn't
you do it in Property1.set immediately as soon as it is set?

Even if so, I would change your code to three bool flags - one per
event handler - and set them in Property1.set, then check them (rather
than comparing old/new property value) in event handlers. That way
you'll avoid repeated string comparisons.
 
K

kirk

Hard to say without knowing what you're really doing.  Typos aside, My  
biggest concern would be the question of whether these events can each be 
raised on different threads.  If they can, then you need some  
synchronization to ensure that when one handler is inspecting and reacting  
to the state of the szProperty1 value, the other isn't changing it  
(otherwise, you might miss a state transition).

Other than that, without additional information, seems fine to me.  :)

Pete

Thanks Pete.

This is single threaded, so no sync issues that I can see. Basically
this is for a RAS tool i'm creating. The first event fires if a class
consumer changes the name of the RAS entry to use in the phone book.
The second event fires if the state of that RAS entry changes and the
third event fires if the statistics on that RAS entry changes. So,
what i'm trying to do is enforce cleanup in the latter two events, to
avoid tracking old state and statistics data, if the RAS entry were to
ever change. I had two thoughts for other options, let the first
event do the cleanup for the state information on the latter two
events, which looks susceptible to the RAS entry changing before the
first event would catch it and the latter two would use it, tracking
old info. Or I don't know if it's possible, but had another idea of
inter-event processing, where I could subscribe the latter two events
to the first event.
 
K

kirk

I have three events, using event handler methods as depicted below.
Two of those event handler methods need to reset specific data
whenever the other event left fires.  I wasn't sure how to properly
implement that, is there a better way than using state management
variables for each timer as i'm doing in the outline below?
private string szProperty1 = null;
// updated by class consumer
public string Property1
{
   get { return this.szProperty1; }
   set { this.szProperty1 = value; }

// state management
private string szProperty1Last1 = null;
private string szProperty1Last2 = null;
private string szProperty1Last3 = null;
private string szProperty2 = null;
private string szProperty3 = null;
[interval: 100ms]
private void EventHandlerMethod1
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast1 != szProperty1, set szPropertyLast1 =
szProperty1, fire event

[interval: 100ms]
private void EventHandlerMethod2
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast2 != szProperty1, set szPropertyLast2 =
szProperty1, reset szProperty2, fire event

[interval: 500ms]
private void EventHandlerMethod3
{
   // exit if szProperty1 == null or no event subscriptions
   // if szPropertyLast3 != szProperty1, set szPropertyLast3 =
szProperty1, reset szProperty3, fire event

Do you really need to do those resets in the event handlers? Couldn't
you do it in Property1.set immediately as soon as it is set?

Even if so, I would change your code to three bool flags - one per
event handler - and set them in Property1.set, then check them (rather
than comparing old/new property value) in event handlers. That way
you'll avoid repeated string comparisons.- Hide quoted text -

- Show quoted text -

Thanks Pavel.

I thought of doing everything from the Property1.set as you
recommended. My fear, as I typically have is of guaranteeing an
atomic update before a timeslice is given to the timer(eventhandler).
For example, user says, update RAS entry name property, Property1.set
updates that single value, and before it gets to the resets, a
timeslice intervenes and executes the eventhandler. At that point the
eventhandler would be tracking old data, on a new property.

Maybe the better route, is to at the start of Property1.set, disable
the timers if they are running, update the variables, then restart the
timers if previously running?
 
P

Pavel Minaev

I thought of doing everything from the Property1.set as you
recommended.  My fear, as I typically have is of guaranteeing an
atomic update before a timeslice is given to the timer(eventhandler).
For example, user says, update RAS entry name property, Property1.set
updates that single value, and before it gets to the resets, a
timeslice intervenes and executes the eventhandler.  At that point the
eventhandler would be tracking old data, on a new property.

What kind of timers do you use - System.Windows.Forms.Timer?
System.Threading.Timer? System.Timers.Timer? The first one won't ever
call an event handler on a different thread, so the situation you
describe simply cannot arise. It is possible for the last two, though.

Anyway, if your handlers are in fact called on a separate thread, then
you just need to use "lock" (or any other convenient synchronization
primitive) as needed to synchronize with any call to Property1.set
that may be in progress.
 
K

kirk

What kind of timers do you use - System.Windows.Forms.Timer?
System.Threading.Timer? System.Timers.Timer? The first one won't ever
call an event handler on a different thread, so the situation you
describe simply cannot arise. It is possible for the last two, though.

Anyway, if your handlers are in fact called on a separate thread, then
you just need to use "lock" (or any other convenient synchronization
primitive) as needed to synchronize with any call to Property1.set
that may be in progress.

Thank you for the additional information Pavel as well as your
patience with my lack of event driven coding. I am using
System.Windows.Forms.Timer, so I should be just fine as each event
will execute one at a time E2E as it drains through the common queue.
Knowing this, and the fact that the Property1 setter method only
executes via an event, i.e. is atomic, I am going to shift all cleanup
code there, as you originally suggested.
 
Top