I have an array of objects and each object has its own timer. If, when constructing the arrayed objects I pass my own timer event handler for use in the timers, is there any way to tell which object's timer has expired.
If not, it seems all the objects in my array would need to catch their own timers and I'd need to implement a completely different delegate that took something like InnerObject as a parameter so the inner objects own event handler could call it like this: OuterDelegate(this,eventArgs);
All the various ways along the same line are such a ridiculous amount of trouble I can't help but think there must be a better way. On other systems the timer always takes a token that is included in parameters to the event handler but I can't find anything resembling that in .net (core).
The answer to your question is fairly simple. The event handler of the System.Timers.Timer Elapsed event is published with an argument called sender.
_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
}
The sender is actually an instance of the System.Timers.Timer class that elapsed.
So, with this you can know the timer that elapsed...
Further more, this class can be extended/Inherited, which means that you can create your own custom Timer class with has an extra property called Name, which you can use to compare and know which timer elapsed.
Example:
class CustomTimer : System.Timers.Timer {
public string TimerName { get; set; }
//More properties as you need
}
//common handler for array of timers
private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
var elapsedTimer = sender as CustomTimer;
if (elapsedTimer.TimerName.Equals(/*which ever*/)) {
//continue with logic
}
// continue with logic
}
Well it turns out that System.Timers is complete junk but not your only choice.
System.Threading.Timer has exactly the features I was looking for. I just didn't realize there were two version until I stumbled on certain complaints that clued me to the fact that they are not the same and I finally looked at the threading version.
Edit:
System.Threading.Timer's callback looks like this
public delegate void TimerCallback(object state);
Where state is an arbitrary object passed to the timer during construction. It can encapsulate anything the event handler needs to properly handle the specific instance of the event. You can even set properties or call methods on the object during event handling thus controlling its state based on the timer.
Edit-2
The only thing in the System.Timers implementation that is vaguely similar is the ability to attach a System.ComponentModel.ComponentCollection and the ability to point to a Component within the collection. These are COM objects belonging to System.Windows.Forms.Control. Even if you extend the class to meet your own needs you drag support for unusable properties around with you.
You can extend the System.Threading.Timer just as easily without dragging unnecessary baggage along.
Related
I have a high rate of events that can occur for a specific entity and i need to transfer them over a network. The problem is that those event can generate high level of traffic and calculation and that is not desired.
So my question would be what would be the best way to delay the execution of calculation function for a specific amount of time. In my case events doesn't have any actual data that i need to buffer or occurrence order so basically it would be just to start a timer once event occurs and fire it with entity parameter once delay expires.
I could build my own implementation with a timer but it seem that there are already ones that should support it e.g reactive extensions ?
In any case if somebody can point me out to an existing implementation or framework would be greatly appreciated.
Edit
Ok, i have looked at RX observable pattern and it looks like it can do the job. I can see a simple implementation that i could use e.g
IDisposable handlers;
Subject<int> subject = new Subject<int>();
handlers = subject.AsObservable().Sample(TimeSpan.FromSeconds(10))
.Subscribe(sample =>
{
Trace.WriteLine(sample);
});
Now whenever i want to process event i would call
subject.OnNext(someValue);
The sample should delay the calls to subscribers.
Can somebody comment if i am correct with this usage?
Here is an example to what you can do:
public class ExpiryDictionarty
{
Timer timer; //will hanlde the expiry
ConcurrentDictionary<string, string> state; //will be used to save the last event
public ExpiryDictionarty(int milisec)
{
state = new ConcurrentDictionary<string, string>();
timer = new Timer(milisec);
timer.Elapsed += new ElapsedEventHandler(Elapsed_Event);
timer.Start();
}
private void Elapsed_Event(object sender, ElapsedEventArgs e)
{
foreach (var key in state.Keys)
{
//fire the calculation for each event in the dictionary
}
state.Clear();
}
public void Add(string key, string value)
{
state.AddOrUpdate(key, value);
}
}
you can create a collection that will save all the events that you receive, once the time ticks you can fire all the events in the collection, because we are using a dictionary we can save only the last event so we don't have to save all the events you get.
I suggest you look into Proxy design pattern. Your clients will know only about a proxy and trigger events on the Proxy object. Your Proxy object will contain the logic that determines when to send actual request over the wire. This logic may depend on your requirements. From what I understood, having a boolean switch isEventRaised and checking it within a configurable interval may suffice your requirements (you will reset the flag to false at the end of this interval).
Also, you may check Throttling implementations first and try to figure out whether they will suite your requirements. For example, here is a StackOverflow question about different Throttling methods, which references among others a Token bucket algorithm.
I have designed a Windows application using C#. The application's form consists of a couple of labels and a button. When the application starts, I instantiate a UdpListener and I start a separate thread with it, so as to achieve responsiveness while the listener waits for incoming packets. When data arrives, the listening thread needs to update the form's controls, and for this I have declared delegate functions and checking for each control if Invoking is required prior to seeing them through these functions.
The application worked fine until now. I now want to implement a timer functionality, such that if a pause of longer than 2 seconds of receiving data has been detected, I would like to turn a label red. I am trying to use the System.Timers.Timer class, and following Microsoft's example (https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx), I have implemented as follows:
private static void SetTimer()
{
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime);
}
I call SetTimer() from my main form. While the above compiles, when I try to substitute Console.... with my controls, say lblStatus, the compiler is complaining that I am trying to reference non static controls from static context. trying to build similar functions as I did for labels and text boxes and using the Invoke method checks does not work either. If anyone has implemented such functionality I would be extremely interested your opinion on this.
In regards to a possible duplication of an existing question on here, please note that I had assumed that the method and event had to be static (as this code was copied from the example cited above), thus the compiler error; I knew what the error meant, I just was puzzled on how I could refer to the form controls from another thread given the static nature of the event. I was also curious as to how come from that static event, Console is still accessible; I guess it's not considered a control. I hope this makes sense to the forum.
You cannot access member variables without an instance reference from a static function. This is because a static function is not part of an instance and it has no access to this.
You should just declare your SetTimer and OnTimedEvent as normal instance methods and declare the timer the same (non-static). That way all your functions will be part of the instance and will have access to other instance variables (controls).
Based on your question, it doesn't seem that you need any of these to be static.
Modify the sender's state in events (aside from being a mutable object), is this considered bad practice?
All event examples I've found are very simple and only do something like Console.WriteLine("event!")
Simple code:
public void HandleEvent(object sender, EventArgs args)
{
ClassA a = (ClassA)sender;
a.doSomething(this.makeSomething());
}
It's not bad practice as such, you need to be careful though.
For instance would it be relevant if dosomething was called from the eventhandler, or directly.
Or because you can't rely on when the eventhandler gets triggered, you are asynchronous, so you can't assume dosomething has been executed before you call dosomethingelse.
E.g dosomething should change state to 2 only if it's 1. If it's not 1 or already 2 more logic is required.
If you start disappearing into that hole, might be better to queue a request to do a dosomething, and then have an engine which deals with the current state and the request queue.
So have a think about how dosomething to a relates to any other methods you call on a. If it's self contained, you are ok, if dependencies start proliferating, than it's bad idea as opposed to a bad practice.
I would not consider it bad practice, as far as you do not make assumptions about the order followed by the runtime to call the event handlers registered with your events. In fact, being that order not guaranteed, you should not rely on that to change the state of your objects, including the sender one.
When using the thread, 'invoke' is being used to avoid 'Cross Thread'(1)
but, sometimes 'timer object' is being used to avoid 'CrossThread' (2)
like this(for example)
public partial class Form1 : Form
{
private bool bCheckState = false;
public Form1()
{
InitializeComponent();
}
//Button Click
private void btnWork_Click(object sender, EventArgs e)
{
Thread m_Thread = new Thread(new ThreadStart(Work));
m_Thread.Start();
}
private void Work()
{
bCheckState = true;
// not use invoke
}
private void timer_Tick(object sender, EventArgs e)
{
if (bCheckState)
{
//tbxDisplay is winform's textBox control - printing data
tbxDisplay.Text = bCheckState.ToString();
bCheckState = false;
}
}
}
which one is more effective? 'between (1) and (2)'
Could it be a problem if we scatter the data processed within 'thread' after checking it in the 'timer event', without using 'invoke' or other methods? (We heard that to avoid 'Cross-Thread' when printing the data processed within 'thread', scattering the data in the 'timer event' with additional 'timer object' has been used quite often as it is neither beneficial nor harmful).
Just use a BackgroundWorker instance and handle the ReportProgress and/or RunWorkerCompleted events, which are already in the right thread.
As Ben Voigt suggested, a BackgroundWorker is probably what you should be using here, unless you have a good reason to want to use something else.
"Effective" is a rather vague means of comparison. Its not entirely clear what you're looking for in the two options you are considering.
BackgroundWorkers are simple and easy to understand, and they avoid the use of timers.
Invoke is more effective than a timer in the sense that there will be less of a delay between bCheckState becoming true and the text being updated. It will also be less CPU-intensive, since you won't have a timer polling at a set interval.
The Timer is more effective in the sense that the thread won't have to stop while invoking to update the text, but it is a bit inefficient because it is going to waste CPU time checking if the boolean has changed, and there could also be a delay of up to the timer interval length before the form changes.
As another alternative, BeginInvoke could be used to update the form without the use of a timer, and without the thread having to wait for the invoke to complete. However, if it raises an exception, your thread might not find out unless you also then call EndInvoke, which will also halt execution of the thread until the invoke is complete.
They all have their advantages and disadvantages, and you can't really call any particular one more "effective" in general.
I'm not sure if I'm entirely clear on the implications of attaching to events in objects.
This is my current understanding, correct or elaborate:
1. Attaching to local class events do not need to be detached
Examples:
this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
public event EventHandler OnMyCustomEvent = delegate { };
I'm assuming that when your object is disposed or garbage collected, the functions are deallocated and would automatically detach from the events.
2. Attaching to objects you no longer need (= null;) have to be detached from
Examples:
Attaching to a timer's Elapsed event, which you only respond to once. I would assume you need to store the Timer in a local variable so you can detached the Elapsed event after the event fires. Thus, declaring the timer in a local method scope like so would result in a leak:
System.Timers.Timer myDataTimer = new System.Timers.Timer(1000);
myDataTimer.Elapsed += new System.Timers.ElapsedEventHandler(myDataTimer_Elapsed);
3. Attaching to events in a local object to your class does not require disposing?
For example, if you had an ObservableCollection that your creates, monitors, and lets die. If you attached to the CollectionChanged event using a local, private function, wouldn't this function deallocate when your class is garbage collected, causing the ObservableCollection to also be freed?
I'm sure I have places where I've stopped using objects and have failed to detach from an event (for example, the timer example I made), so I'm looking for a clearer explanation on how this works.
I think you're making it more complicated than it needs to be. You just need to remember two things:
When you subscribe to an event, the event's "owner" (the publisher) generally keeps a reference to the delegate you subscribe with.
If you use an instance method as the action of a delegate, then the delegate has a reference to its "target" object.
This means that if you write:
publisher.SomeEvent += subscriber.SomeMethod;
Then subscriber won't be eligible for garbage collection before publisher is unless you unsubscribe later.
Note that in many cases, subscriber is just this:
publisher.SomeEvent += myDataTimer_Elapsed;
is equivalent to:
publisher.SomeEvent += this.myDataTimer_Elapsed;
assuming it's an instance method.
There is no reverse relationship just due to event subscription - in other words the subscriber doesn't keep the publisher alive.
See my article on events and delegates for more information, by the way.
The remaining references preventing garbage collection has one more effect that may be obvious but nontheless not yet stated in this thread; the attached event handler will be excuted as well.
I have experienced this a couple of times. One was when we had an application that gradually became slower and slower the longer it run. The application created the user interface in a dynamic fashion by loading user controls. The container made the user controls subscribe to certain events in the environment, and one of these were not unsubscribed from when the controls were "unloaded".
After a while this led to a large number of event listeners being executed each time that particular event was raised. This can of course lead to serious race conditions when a good number of "sleeping" instances suddenly wake up and try to act on the same input.
In short; if you write code to hook up an event listener; make sure that you release as soon as it's not needed any longer. I almost dare to promise it will save you from at least one headache at some point in the future.
The relevant case where you have to unsubscribe from an event is like this:
public class A
{
// ...
public event EventHandler SomethingHappened;
}
public class B
{
private void DoSomething() { /* ... */ } // instance method
private void Attach(A obj)
{
obj.SomethingHappened += DoSomething();
}
}
In this scenario, when you dispose of a B, there will still be a dangling reference to it from obj's event handler. If you want to reclaim the B's memory, then you need to detach B.DoSomething() from the relevant event handler first.
You could run into the same thing if the event subscription line looked like this, of course:
obj.SomethingHappened += someOtherObject.Whatever.DoSomething();
Now it's someOtherObject that's on the hook and can't be garbage collected.