好的,我在.Net 4中使用System.Timers.Timer
和C#。
我有我的计时器对象:
var timer = new Timer {Interval = 123};
我的Timer Elapsed事件处理程序指向一个类似的方法:
timer.Elapsed += MyElapsedMethod;
我的方法看起来像这样:
static void MyElapsedMethod(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Foo Bar");
}
我想将一个字符串传递给这个方法,我该怎么做?
由于
答案 0 :(得分:68)
最简单的方法是将事件处理程序更改为匿名函数。它允许您在声明点传递字符串。
string theString = ...;
timer.Elapsed += (sender, e) => MyElapsedMethod(sender, e, theString);
static void MyElapsedMethod(object sender, ElapsedEventArgs e, string theString) {
...
}
答案 1 :(得分:15)
如果您希望能够再次取消注册“Elapsed”事件处理程序,则不应在不记住变量的情况下使用委托。
所以另一种解决方案可能是基于Timer创建一个自定义类。只需添加您喜欢的任何成员,并从“Elapsed”事件处理程序的“sender”参数中获取自定义Timer对象:
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;
}
这个策略当然适用于其他事件和类,只要基类没有被密封。
答案 2 :(得分:2)
您可以将字符串保存在某个对象中并在事件处理程序中读取它:
static string _value;
static void MyElapsedMethod(object sender, ElapsedEventArgs e)
{
Console.WriteLine(_value);
}
更新:通过不同语法的相同代码:
timer.Elapsed += (s,e) => Console.WriteLine(_value);
更新:考虑使用System.Threading.Timer而不是
State state = new State();
Timer timer = new Timer(OnTimer, state, 0, 123);
state.Value = "FooBar"; // change state object
您可以在计时器回调中检索状态:
static void OnTimer(object obj)
{
State state = obj as State;
if (state == null)
return;
Console.WriteLine(state.Value);
}
答案 3 :(得分:1)
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)
{
};
答案 4 :(得分:0)
使用同一个类中的字段来保存所需的任何字符串,然后在已用事件处理程序中检索它。但是,您必须小心交叉线程问题。
答案 5 :(得分:0)
我写了这个简单的类来处理这个问题:
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();
}
像这样使用它:
void Main(string[] args){
new MyTimer(durationInSeconds * 1000, EventHandler, "some string");
}
void EventHandler(object param){
doSomethingWithString((string)param);
}
如果您编辑委托(以及MyTimer
类中的事件处理程序的调用),则还可以传递事件参数或任何类型的参数。
答案 6 :(得分:0)
为什么不只使用Timer和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!");
}
}
}