I want to pass a variable into a function that is run after a delay. I've seen similar question on how to do this (see below). I dont think this is what I want as I each time method1 is called, the number of attached anonymous functions grows? What I need to do is remove any existing attached anonymous function before adding the new one. But I dont think this possible. Is there a way to call a method after a delay but pass in a new value of a variable each time?
using System.Timers;
myTimer = new Timer();
myTimer.Interval = 3000;
myTimer.AutoReset = false;
public void method1(int var1){
myTimer.Elapsed += delegate { doSomething(var1); };
myTimer.Start();
}
public void doSomething(int arg1){...}
UPDATE
Basically whenever method1 is run, I want something to happen 3 secs later, and I need to pass in an argument that may vary each time.
I dont think I can use a field to store the variable because method1 may be called several times before the first timer expires. I.e. there could be several qued up. E.g. at one point in time the que of 'doSomething' waiting to happen could be...
doSomething(3)
doSomething(7)
doSomething(1)
It is just used in a testbench, and method1 will be run called no more than 50 times. What I want to ensure is that each doSomething(var1) only gets called once and not every 3 secs. Ie there is only one doSomething called each time method1 is called.
This is for a windows console app.
Using the TPL (& .Net 4.5), you can do something like this:
public static class ActionExtensions
{
public static async void DelayFor(this Action act, TimeSpan delay)
{
await Task.Delay(delay);
act();
}
}
//usage
Action toDo = () => doSomething(var1);
toDo.DelayFor(TimeSpan.FromSeconds(3));
... or this may be simpler for your app:
static async void DoSomethingLater(int n)
{
await Task.Delay(TimeSpan.FromSeconds(3));
//DoSomething(n);
}
//usage
void Method1(int n)
{
DoSomethingLater(n);
}
There's no good way to do that using System.Timers.Timer.
With System.Threading.Timer, you can pass a userState object to the constructor. That object is then passed to the timer callback with every tick. For example:
string Whatever = "foo";
System.Threading.Timer timer =
new System.Threading.Timer(MyTimerCallback, whatever, 100, 100);
void MyTimerCallback (object state)
{
string theData = (string)state;
// at this point, theData is a reference to the "Whatever" string.
// do tick processing
}
You could, if you want, extend System.Timers.Timer, and add a property to hold your data. Something like:
class DerivedTimer : System.Timers.Timer
{
public string Foo { get; set; }
}
myTimer = new DerivedTimer();
myTimer.Interval = 3000;
public void methodRunRegularly(int var1){
myTimer.Foo = "Foobar!";
myTimer.Elapsed += doSomething;
myTimer.Start();
}
public void doSomething(object sender, EventArgs e)
{
var t = (DerivedTimer)sender;
var foo = t.Foo;
// do processing
}
A reference to the timer is passed in the sender parameter. You can just cast that and then reference the Foo property that you set when you initialized the timer.
This makes use of Reactive Extensions (use nuget package "rx-main").
Run a method with a 3 second delay:
public void method1(int value)
{
ThreadPoolScheduler.Instance.Schedule(
TimeSpan.FromSeconds(3), () => doSomething(value));
}
That's about as short as it gets!
Related
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.
I am trying out the ExcelAsyncUtil.Observe function. I made the following code that shows a running clock in Excel. It works fine but I am not sure what I am doing. Two questions:
Should I add functionality for observer.OnCompleted() and observer.OnError()? What does these calls do?
What should I do in the IDisposible class? Why is it there?
Here is my sample code:
[ExcelFunction]
public static object MyExcelTicker()
{
return ExcelAsyncUtil.Observe("MyExcelTicker", new object[] { }, TickerFunction());
}
public static ExcelObservableSource TickerFunction()
{
ExcelObservableSource source = new ExcelObservableSource(() => new TickerObservable());
return source;
}
public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();
// What about observer.OnCompleted() and observer.OnError()?
return new TickerDisposable();
}
}
public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}
It has been a while and at least one thing is still left not covered, so let me add to what Govert said.
You've asked:
public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}
Let's summarize:
For each new subscriber to your clock-ticker, a Subscribe will be called on the TickerObservable. Therefore, for each subscriber, your code will create a new System.Timers.Timer and a new timer.Elapsed event handler - to get your intended effect. And this is actually all that you need to get your effect.
However, you are also required to return an IDisposable, therefore you've created a dummy TickerDisposable solely for that purpose, and you are not sure what it is for.
Answer:
The IDisposable that the library requires you to return from the Subscribe is there just to allow you to cleanup after your glitter stops shining. Timers are a "system thing". Once you create them and start them, they run. After an hour they cannot be GC'ed, because they are meant to be run until you stop them. Surely, you've +='ed an event hander, the observer (if weakly-reference'd) might be already dead, but your timer does not know! You must stop it at some point.
Hence, IDisposable-related pattern, borrowed from RX: whatever heavy or long-living you allocate, reserve, build, etc in the Subscribe method, put some note about it into that (yours!) IDisposable. Then, when the observer unsubscribes, your IDisposable will get cleaned too, and your custom Dispose method will be run, that will be able to look at your IDiposable's contents and .. cleanup the garbage, or rather, unlock it, so the GC can flush them.
Completing your example:
public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();
return new TickerDisposable(timer);
}
}
public class TickerDisposable : IDisposable
{
private Timer ticky;
public TickerDisposable(Timer timer)
{
ticky = timer;
}
public void Dispose()
{
if(ticky != null)
ticky.Dispose(); // or Stop, or etc..
}
}
The above example is actually most-obvious usage of the returned IDisposable. However, you can use it for any register-unregister notification. For example, with single shared timer, it might look like this:
public class TickerObservable : IExcelObservable
{
private static Timer timer = ..... ; // assume it is up & running & shared
public IDisposable Subscribe(IExcelObserver observer)
{
ElapsedEventHander hd = (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Elapsed += hd;
return new TickerDisposable(timer, hd);
}
}
public class TickerDisposable : IDisposable
{
private Timer ticky;
private ElapsedEventHander handler;
public TickerDisposable(Timer timer, ElapsedEventHander hd)
{
ticky = timer;
handler = hd;
}
public void Dispose()
{
if(ticky != null && handler != null)
ticky.Elapsed -= handler;
}
}
And now you are perfectly sure that no dead-handlers are lingering at the long-living-shared-timer. (of course the cleanup of the timer is missing here, but that's another thing..). Probably you already got the idea, so, have fun!
The IExcelObserver interface matches the semantics of the IObserver interface from the Reactive Extensions library (http://msdn.microsoft.com/en-us/library/dd783449.aspx).
You function can call OnNext zero or more times, and then call OnError if an error occurs, or OnCompleted if no further events will be raised. Excel-DNA will handle OnError as it would an exception thrown by a regular UDF, and will return #VALUE to the cell or process the exception via the registered UnhandledExceptionHandler. OnCompleted is not so useful in the Excel context - it just indicates that no further values will be raised.
For your example, error don't seem to be a problem, and there is no end to the stream of events, so you need never call OnError or OnCompleted.
The Excel-DNA infrastructure will call the IDisposable.Dispose when the observable is no longer hooked up to a cell formula. For example, if the formula with the MyExcelTicker() call is deleted from the cell. You can use this as a notification to clean up any back-end resources, or ignore the notification if you're not interested.
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
}
We have this common scenario where we have a method that performs some action asyncronously and raises an event when it's done.
There are times where we want it done synchronously instead so we have code that looks similar to this:
ManualResetEvent reset = new ManualResetEvent(false);
someobject.AsyncActionDone += (sender, args) => reset.Set();
someobject.PerformAsyncAction();
reset.WaitOne();
Is there a way to write a helper method to do this? I can pass in the Action to perform, but I'm not sure how to pass in something that lets the helper method know which event to listen to since it doesn't look like you can pass in an EventHandler as a parameter.
Preferably a solution that doesn't require reflection
There seems to be some confusion, this is a sample of what someobject's class is like:
public class SomeClass
{
private ExternalServer someServerOverTheNetwork = new ExternalServer();
public event EventHandler AsyncActionDone;
public Data SomeData { get; set; }
public void PerformAsyncAction()
{
someServerOverTheNetwork.GetSomeData(OnDataRetrived);
}
public Data OnDataRetrived(Data someData)
{
AsyncActionDone(this, new DataEventArgs(someData));
}
}
I would consider implementing the Asynchronous Design Pattern in the objects that performs asynchronous operation.
public object Operation(object arg)
{
var ar = BeginOperation(arg, null, null);
return EndOperation(ar);
}
public IAsyncResult BeginOperation(object arg, AsyncCallback asyncCallback, object state)
{
AsyncResult asyncResult = new AsyncResult(asyncCallback, state);
// Lauch the asynchronous operation
return asyncResult;
}
private void LaunchOperation(AsyncResult asyncResult)
{
// Do something asynchronously and call OnOperationFinished when finished
}
private void OnOperationFinished(AsyncResult asyncResult, object result)
{
asyncResult.Complete(result);
}
public object EndOperation(IAsyncResult asyncResult)
{
AsyncResult ar = (AsyncResult)asyncResult;
return ar.EndInvoke();
}
With this pattern you have the flexibility of having multiple concurrent asynchronous operation on your object.
Note: You can easily find an implementation of a generic AsyncResult class on the web.
Edit:
As you want to keep the current design, if all your object can only have one asynchronous operation, then you could define an IAsyncOperation interface and implement it in all your object.
public interface IAsyncOperation
{
event EventHandler AsyncActionDone;
void PerformAsyncAction();
}
Then you could have:
public static CallSynchronously(IAsyncOperation asyncOperation)
{
ManualResetEvent reset = new ManualResetEvent(false);
asyncOperation.AsyncActionDone += (sender, args) => reset.Set();
asyncOperation.PerformAsyncAction();
reset.WaitOne();
}
If your objects can contain multiple asynchronous operation, then without reflection I think there is no way to achieve what you want to do, but you could still define a synchronous version of all asynchronous operation that wraps the ManualResetEvent.
public void PerformAction()
{
ManualResetEvent reset = new ManualResetEvent(false);
this.AsyncActionDone += (sender, args) => reset.Set();
this.PerformAsyncAction();
reset.WaitOne();
}
If i catch your drift, you can simply use delegates in the following way,
create a delegate for you function call, lets call it
public delegate string AsyncDelegate();
then, create a proxy function like this:
public static void ExecuteSync(AsyncDelegate func)
{
ManualResetEvent reset = new ManualResetEvent(false);
int threadId;
func.BeginInvoke((a)=>reset.Set(), null);
reset.WaitOne();
}
Thats all, you can make it a bit more complex by adding another function delegate to run after completion or something like that..
Enjoy!