How do I pass an object into a timer event?

2019-01-13 21:07发布

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

标签: c# timer
5条回答
聊天终结者
2楼-- · 2019-01-13 21:56

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.

查看更多
孤傲高冷的网名
3楼-- · 2019-01-13 21:57

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);
}
查看更多
淡お忘
4楼-- · 2019-01-13 22:00

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.

查看更多
Emotional °昔
5楼-- · 2019-01-13 22:01

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) {
  ...
}
查看更多
beautiful°
6楼-- · 2019-01-13 22:10
 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)
{
};
查看更多
登录 后发表回答