Reputation: 28059
Ok so I am using System.Timers.Timer
in .Net 4 with C#.
I have my timer object like so:
var timer = new Timer {Interval = 123};
I have my Timer Elapsed event handler pointed at a method like so:
timer.Elapsed += MyElapsedMethod;
And my method looks like this:
static void MyElapsedMethod(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Foo Bar");
}
I want to pass a string into this method, how do I do this?
Thanks
Upvotes: 58
Views: 76740
Reputation: 1
Why not just use a Timer and an ElapsedEventHandler?
namespace TimerEventHandler
{
class Program
{
private static Timer myEventTimer;
static void Main(string[] args)
{
// 5 second timer multiply 1000 milliseconds by the time
//e.g. new Timer(60 * 1000 * 10) = 10 minutes
myEventTimer = new Timer(5 * 1000 * 1);
myEventTimer.Enabled = true;
myEventTimer.Elapsed += new ElapsedEventHandler(TimerSchedule_Elapsed);
Console.WriteLine("Timer started!");
// make a thread and wait forever just so console does not go away
Thread.Sleep(Timeout.Infinite);
}
private static void TimerSchedule_Elapsed(object sender, ElapsedEventArgs e)
{
// do something
Console.WriteLine("Timer elapsed!");
}
}
}
Upvotes: -1
Reputation: 784
I wrote this simple class to handle this:
using System;
using System.Timers;
namespace MyProject.Helpers
{
public class MyTimer
{
private volatile Timer _timer = new Timer();
private volatile bool _requestStop = false;
private MyElapsedEventHandler _eventHander;
private MyElapsedEventHandlerWithParam _eventHandlerWithParam;
private object _param;
public MyTimer(int interval, MyElapsedEventHandler elapsedEventHandler, bool autoReset = false)
{
_timer.Interval = interval;
_timer.Elapsed += ElapsedWrapper;
_timer.AutoReset = autoReset;
_eventHander = elapsedEventHandler;
Start();
}
public MyTimer(int interval, MyElapsedEventHandlerWithParam elapsedEventHandler, object param, bool autoReset = false)
{
_timer.Interval = interval;
_timer.Elapsed += ElapsedWrapperWithParam;
_timer.AutoReset = autoReset;
_eventHandlerWithParam = elapsedEventHandler;
_param = param;
Start();
}
private void ElapsedWrapper(object sender, ElapsedEventArgs e)
{
if (!_requestStop && _eventHander != null)
{
_eventHander();
}
}
private void ElapsedWrapperWithParam(object sender, ElapsedEventArgs e)
{
if (!_requestStop && _eventHandlerWithParam != null)
{
_eventHandlerWithParam(_param);
}
}
public void Stop()
{
_requestStop = true;
_timer.Stop();
}
public void Start()
{
_requestStop = false;
_timer.Start();
}
}
public delegate void MyElapsedEventHandlerWithParam(object param);
public delegate void MyElapsedEventHandler();
}
use it like this:
void Main(string[] args){
new MyTimer(durationInSeconds * 1000, EventHandler, "some string");
}
void EventHandler(object param){
doSomethingWithString((string)param);
}
you can also pass the event arguments or any kind of parameters if you edit the delegate (and the call of the event handler in MyTimer
class).
Upvotes: 0
Reputation: 457
Timer aTimer = new Timer(300);
aTimer.Elapsed += delegate { PublishGPSData(channel, locationViewModel); };
// Hook up the Elapsed event for the timer.
aTimer.AutoReset = true;
aTimer.Enabled = true;
private void PublishGPSData(IModel channel, LocationViewModel locationViewModel)
{
};
Upvotes: 1
Reputation: 1843
If you want to be able to unregister your "Elapsed" event handler again, you shouldn't use a delegate without remembering it in a variable.
So another solution could be to create a custom class based on Timer. Just add whatever members you like and get your custom Timer object back from the "sender" argument of the "Elapsed" event handler:
class CustomTimer : System.Timers.Timer
{
public string Data;
}
private void StartTimer()
{
var timer = new CustomTimer
{
Interval = 3000,
Data = "Foo Bar"
};
timer.Elapsed += timer_Elapsed;
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
string data = ((CustomTimer)sender).Data;
}
This strategy of course works for other events and classes too, as long as the base class is not sealed.
Upvotes: 35
Reputation: 236248
You can save string in some object and read it in event handler:
static string _value;
static void MyElapsedMethod(object sender, ElapsedEventArgs e)
{
Console.WriteLine(_value);
}
UPDATE: same code via different syntax:
timer.Elapsed += (s,e) => Console.WriteLine(_value);
UPDATE: Consider also using System.Threading.Timer instead
State state = new State();
Timer timer = new Timer(OnTimer, state, 0, 123);
state.Value = "FooBar"; // change state object
You can retrieve state in timer callback:
static void OnTimer(object obj)
{
State state = obj as State;
if (state == null)
return;
Console.WriteLine(state.Value);
}
Upvotes: 2
Reputation: 45145
Use a field in the same class to hold whatever string you want and then retrieve it in you elapsed event handler. You'll have to be careful about cross-threading issues however.
Upvotes: 0
Reputation: 754803
The easiest way to do this is to change the event handler into an anonymous function. It allows you to pass the string at the point of declaration.
string theString = ...;
timer.Elapsed += (sender, e) => MyElapsedMethod(sender, e, theString);
static void MyElapsedMethod(object sender, ElapsedEventArgs e, string theString) {
...
}
Upvotes: 130