I'm working on a program and I wanted to know the best way I can get information from one class to another.
My purpose is to get information from MyTimer to the Program class about how much "ticks" the timer did.
** I don't want from the class MyTimer to be dependent on the Program class (Like by using Program.SetUpdate()). MyTimer class should work with every class without changing his code.
I've already tried using public static method to send the information.
class Program
{
private static int _count;
private static MyTimer _myTimer;
static void Main(string[] args)
{
_count = 0;
_myTimer = new MyTimer() { Timer_Interval = 100 };
_myTimer.Start();
do
{
Console.WriteLine("Press q to quit.");
} while (Console.ReadKey().KeyChar.ToString().ToLower() != "q");
_myTimer.Stop();
}
public static void SetUpdate(int count)
{
_count = count;
Print();
}
private static void Print()
{
Console.WriteLine(_count);
}
}
class MyTimer
{
private Timer _timer;
private int _ticks;
public int Timer_Interval { get; set; }
public MyTimer()
{
_timer = new Timer();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Program.SetUpdate(_ticks);
_ticks++;
}
public void Start()
{
if (Timer_Interval == 0)
throw new InvalidOperationException("_timer interval can not be 0.");
_ticks = 0;
_timer.Interval = Timer_Interval;
_timer.Start();
}
public void Stop()
{
_timer.Stop();
}
}
The output is 1,2,3... until you press q/Q
I've tried to do it as simple as I can only to show you the concept.
So I created a class named Program that call MyTimer class.
MyTimer class is simply like a timer: stop,start and elapsed. Each interval it makes a "tick".
You'd normally fix this sort of issue by establishing a "direction". E.g. here it feels natural that it should be "from" Program "to" MyTimer. In that given direction, it's perfectly fine to make direct method calls, access properties, etc.
When you need information to flow in the other direction, that's when you use events. MyTimer raises an event and Program can have a handler. In this way, MyTimer doesn't know which classes are creating it/working with it or even how many event handlers have been installed.
I think Damien nailed it pretty much for this scenario.
Yet, I'd like to propose an alternative: Using a shared State Object.
You could define a State class, which does nothing else than hold the value of the tick-count.
You'd instanciate it in Program and pass it to the MyTimer. Mind that both classes now share the same instance (possibly introducing threading/concurrency issues if in multithreaded context).
MyTimer then would update the state on that shared Object.
Examples are Model/ViewModel classes in MVVM/WPF where you would bind some Control's property to that object's property.
Mind that Program wouldn't know of a occurring change out of the box. So that would have to be handled additionally. Either again via an Event, some "Observer Pattern" or similar.
As I said, events are the way to go here but I thought it couldn't hurt to suggest an alternative way of inter-class communication.
Related
So, I have this class for dealing with timers in MVVM:
class RecognitionProcessTimer
{
DispatcherTimer analysisProcessTimer;
public int Duration { get; set; }
public RecognitionProcessTimer()
{
this.Duration = 500;
}
public void StartTimer()
{
analysisProcessTimer = new DispatcherTimer();
analysisProcessTimer.Interval = TimeSpan.FromMilliseconds(this.Duration);
analysisProcessTimer.Tick += AnalysisProcessTimer_Tick;
analysisProcessTimer.Start();
}
public void StopTimer()
{
if (analysisProcessTimer != null)
{
analysisProcessTimer.Stop();
analysisProcessTimer = null;
}
}
private void AnalysisProcessTimer_Tick(object sender, object e)
{
analysisProcessTimer.Stop();
// C# code current object variables from the other class
}
}
So, I have an analysis class that will do analysis on every tick of the timer. The RecognitionProcessTimer will be initialized and Start() on this analysis class's code but the timer's AnalysisProcessTimer_Tick event needs to check and call some current analysis class object variables. How do I go on achieving this?
I've tried to initialize the analysis class on tick method but then I lose all the data on there as a new object is used instead of the using the object that initialize the RecognitionProcessTimer class.
TLDR: I'm trying to use the variables from the class that initialized RecognitionProcessTimer from RecognitionProcessTimer's tick method.
If the question seems unclear, then please let me know and I'll clarify further.
P.S: Can't use static variables.
I am trying to make a global timer where everything that needs to be notified after certain time has passed.
For instance, in a game, there would be buffs and attack cool down timers and item cool down and much more.
Managing them separately is fine, but how would I make them all to run on same timer?
I was tried using SortedList with a float as key and a delegate as value to be simply invoked when time is up, but I cant seem to manage it. Tried delegate with Generic parameter but I can't put that into a sorted list.
Can anyone point me in the right direction?
I can point out 2 options:
Create an interface like TimerControlled (all names can be changed) With a method TimerTick(whatever arguments you need) (and others if needed) , which implements your timer tick logic for that class. Implement the interface the on each class that uses timer dependent mechanics. Finally on your base (logic) class add all of your TimerControlled object to an array (of TimerControlled) which will allow you to cycle through that array and call TimerTick methods of those object with 2 lines of code.
Interface:
interface TimerControlled
{
void TimerTick();
}
Implement it in each of your classes:
public class YourClass: TimerControlled{
....
public void TimerTick(){
advanceCooldown();
advanceBuffTimers();
}
}
finally add your classes to a list of TimerControlled:
class YourLogicClass{
List<YourClass> characters= new List<YourClass>();
private timer;
List<TimerControlled> timerControlledObjects = new List<TimerControlled>();
...
public void Initialize(){
... //your code, character creation and such
foreach(YourClass character in characters){ //do the same with all objects that have TimerControlled interface implemented
timerControlledObjects.add(character);
}
timer = new Timer();
timer.Tick += new EventHandler(timerTick)
timer.Start();
}
public void timerTick(Object sender, EventArgs e){
foreach(TimerControlled timerControlledObject in timerControlObjects){
timerControlledObject.TimerTick();
}
}
}
(not a very good option in the long run) Static timer in a static class, like Global.timer, which will mean only 1 instance of that timer will exist. Then attach an event handler to timer from each relevant class to handle timer ticks.
Code:
public static class Global{
//I usually create such class for global settings
public static Timer timer= new Timer();
}
class YourLogicClass{
public void Initialize(){
...
Global.timer.Start();
}
}
class YourClass{
public YourClass(){
Global.timer.tick += new EventHandler(timerTick);
}
private void timerTick(Object sender,EventArgs e){
advanceCooldowns();
advanceBuffTimers();
}
}
Keep in mind that I've written the code off the top of my head, so some syntax errors might be there, but the logic is right.
If you have further questions regarding the answer ask away.
I'm reading values from a certain process memory. Let's say that I fetch them in the following way:
var foo = memoryService.GetFoo();
var bar = memoryService.GetBar();
Since it doesn't exist any events for memory changes, I would like to create custom events using polling (if you don't have any other suggestions).
Since I don't know when the values might change, the polling interval has to be set to a suitable value. I don't know how to actually write this, but something like this might do (not sure if it compiles):
public class MemoryChange : INotifyPropertyChanged
{
private Timer _timer;
public SomethingChanged(double polingInterval)
{
_timer = new Timer();
_timer.AutoReset = false;
_timer.Interval = polingInterval;
_timer.Elapsed += timer_Elapsed;
_timer.Start();
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
}
}
Do I need to create one class that implements INotifyPropertyChanged for each value (foo and bar in this case)?
Is there any way to make it run on a non blocking thread (using a Task perhaps?)?
Do I have to use polling to make this work?
Any input is much appreciated!
If you have access to your MemoryService from your main view model, then you could define a simple delegate to solve your problem.
In your MemoryService, define the delegate and related property:
public delegate void DataUpdate(object someData);
public DataUpdate OnDataUpdate { get; set; }
In the parent view model, attach a handler for the delegate:
MemoryService memoryService = new MemoryService();
memoryService.OnDataUpdate += MemoryService_OnDataUpdate;
Back in MemoryService when the data is ready:
var foo = memoryService.GetFoo();
// Always check for null
if (OnDataUpdate != null) OnDataUpdate(foo);
Now in the parent view model:
public void MemoryService_OnDataUpdate(object someData)
{
// Do something with the new data here
}
You can find out more about using delegate objects from the Delegates (C# Programming Guide) page on MSDN.
I am not sure in what context you will be using your memory service though I will give it a try to answer your quesiton.
Yes, you will have to implement INotifyPropertyChanged in every class.
Yes there is a way, Google knows it.
You can use polling or you could listen to PropertyChanged event. That would be the callback approach where you get notified when a changes happened.
I've been reading over the questions about unit testing with timers and threading. I found the SO question about unit testing system.threading.timers, but I need to unit test a system.timers.timer and a wrapper class doesn't seem to work quite as smoothly for this one.
I just need to know how to mock the timer and/or system time in order to unit test against it. I can't seem to find this anywhere on google.
edit & update:
It makes sense that if I extract the timer by wrapping it as below, I can generate a timer and use mocking to replace it with a different timer. The relevant part is then to take that timer that I'm injecting at runtime (the original, not a mock) and test it's elapsed event code.
What stops you from wrapping this one?
public interface ITimer
{
void Start(double interval);
void Stop();
event ElapsedEventHandler Elapsed;
}
That's pretty much all your interface needs. Let's see how this could go (note that you could of course expose more Timer properties, but that's pretty much basic stuff that should be enough):
public class MyTimer : ITimer
{
private Timer timer = new Timer();
public void Start(double interval)
{
timer.Interval = interval;
timer.Start();
}
public void Stop()
{
timer.Stop();
}
public event ElapsedEventHandler Elapsed
{
add { this.timer.Elapsed += value; }
remove { this.timer.Elapsed -= value; }
}
}
Now, how would you utilize this in your testing (assuming we're using FakeItEasy as mocking framework of choice):
var timerFake = A.Fake<ITimer>();
var classUnderTest = new MyClass(timerFake);
// tell fake object to raise event now
timerFake.Elapsed += Raise.With<ElapsedEventArgs>(ElapsedEventArgs.Empty).Now;
// assert whatever was supposed to happen as event response, indeed did
Assert.That(classUnderTest.ReceivedEvent, Is.True);
Example above actually does test the code that happens once the event on timer is raised. Consider MyClass looking like this:
public class MyClass
{
private ITimer timer;
public MyClass(ITimer timer)
{
this.timer = timer;
this.timer.Elapsed += TimerElapsedHandler;
}
public bool ReceivedEvent { get; set; }
private void TimerElapsedHandler(object sender, ElapsedEventArgs e)
{
ReceivedEvent = true;
}
}
In the test, we force timer to raise when we need it, and we check whether code in TimerElapsedHandler executed, by asserting ReceivedEvent property was set. In reality, this method might do more than that, but that will only change the way we do assertions - idea remains the same.
Edit: You can also try Moles, a framework that allows you to generate fakes of any framework types/methods. However, if mocking timer was all you wanted, I'd go with wrapper approach.
You need to test the timer or test the code executed in each event? If so, you can put that logic in another class and just test that. You can trust the timer will call it...
I cant figure out how to proceed the best way with this problem.
Right now I have a windows service which only task is to gather data from a database with a specific DSN and then send out an email if the data is valid. The service contains a timer which ticks every 5 minuts and performs the tasks above.
Now I need to re-write the windows service to be able to run on more than 1 DSN.
I was thinking of making several threads inside the windows service and then again have a seperat timer inside each thread.
Is this a good idea and how can this be done? I want to avoid having a windows service for each DSN.
Ill try to draw it if I dont make any sense
Windows Service
Thread1(DSN1)-----------------------------Thread2(DSN2)----------------------Thread3(DSN3)
Timer(ticks every X minuts)-----------------Timer(same)-------------------------Timer(same)
Logic()---------------------------------------------Logic---------------------------------Logic()
Hope my problem makes sense :)
As far as I Know each timer represents a thread on its own. Knowing this, I would try to dynamically create timer objects for each given dsn.
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
private List<GetDataFromDSN> list = null;
protected override void OnStart(string[] args)
{
list = new List<GetDataFromDSN>();
// assume args contains your given dsn values
foreach (string dsn in args)
{
GetDataFromDSN newObj = new GetDataFromDSN();
newObj.DSN = dsn;
list.Add(newObj);
newObj.Start();
}
}
}
public class GetDataFromDSN
{
public string DSN { get; set; }
private Timer timer = null;
private double interval = 1000*60*5; // 5 minutes interval
public GetDataFromDSN()
{
// init your object
timer = new Timer(interval);
timer.Elapsed +=new ElapsedEventHandler(timer_Elapsed);
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
// do what ever you want
}
public void Start() // or even make timer public
{
timer.Start();
}
public void Stop()
{
timer.Stop();
}
}
Do each of the DSNs need to be on a separate Thread?
If you were to encapsulate the Email retrieval and validation logic within some sort of service that the Thread invoked, the fact that there were multiple DSNs could be hidden from the scheduling thread. For instance, an IEmailService might have the following contract:
public interface IEmailService
{
void SendEmailsToValidAddresses();
}
and the implementation might look something like this:
public class MultipleSourcesEmailService : IEmailService
{
private IEnumerable<IDatabaseSource> databases;
public EmailService(params IDatabaseSource[] sources)
{
databases = new List<IDatabaseSource>(sources);
}
public void SendEmailsToValidAddresses()
{
foreach(var database in databases)
{
var emailAddresses = database.SelectAllEmailAddresses();
ValidateAndSendEmailsTo(emailAddresses);
}
}
public void ValidateAndSendEmailsTo(IEnumerable<string> emailAddresses)
{
// Perform appropriate logic
...
}
}
In this way, your timer logic can remain the same and on a single Thread whilst the concern of sending emails is separated into the IEmailService. This also means that you could implement a SingleSourceEmailService and a MultipleSourceEmailService and swap the multiple sources in when you're code complete and the consumer of the service need never know.
Of course, the EmailService as implemented above will SendEmails from multiple sources sequentially - if you need it to run in parallel you could change the EmailService to kick off a new Thread for each of the DSNs that you have, you could even call it the: MultiThreadedMultipleSourceEmailService but as a consumer of the IEmailService your scheduling will never know the difference.
Use a backgroundworker.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Just start one for each DSN, very smooth and easy to use.
Try using System.Threading.Timer
Here is sample code from my project, Hope this helps
public void StartDSNTimers()
{
_tmr1 = new Timer(CheckMessages, dsn1, 0, 60000);
_tmr2 = new Timer(CheckMessages, dsn2, 0, 60000);
_tmr3 = new Timer(CheckMessages, dsn3, 0, 60000);
}
private void CheckMessages(object obj)
{
//Logic
}