C# 如何将对象传递给计时器事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9977393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 11:27:37  来源:igfitidea点击:

How do I pass an object into a timer event?

c#timer

提问by JMK

Ok so I am using System.Timers.Timerin .Net 4 with C#.

好的,所以我System.Timers.Timer在 .Net 4 中使用 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 事件处理程序指向这样的方法:

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

谢谢

采纳答案by JaredPar

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) {
  ...
}

回答by Sergey Berezovskiy

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);

更新:通过不同语法的相同代码: timer.Elapsed += (s,e) => Console.WriteLine(_value);

UPDATE: Consider also using System.Threading.Timer instead

更新:考虑使用 System.Threading.Timer 代替

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);
}

回答by Matt Burland

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.

使用同一类中的字段来保存您想要的任何字符串,然后在经过的事件处理程序中检索它。但是,您必须小心跨线程问题。

回答by Michael Geier

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.

如果您希望能够再次取消注册您的“Elapsed”事件处理程序,您不应该在没有记住变量的情况下使用委托。

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:

所以另一个解决方案可能是创建一个基于 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;
}

This strategy of course works for other events and classes too, as long as the base class is not sealed.

只要基类没有密封,这个策略当然也适用于其他事件和类。

回答by Mahendra

 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)
{
};

回答by lennyy

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 MyTimerclass).

如果您编辑委托(以及MyTimer类中事件处理程序的调用),您还可以传递事件参数或任何类型的参数。