0
votes

I want to build MyTimer class but can't get method name as parameter. It says "Cannot access non-static method 'TimerCallBack' in static context. I know it's ok if method is static but i want to use this class for both static and non-static timercallback methods. I can do that directly give method name to timer object in test class but when i try to give to MyTimer and use this parameter in timer object, it's not working. How can i solve this problem?

class MyTimer
{
    private System.Threading.Timer _timer;
    private int _period;
    private int _dueTime;

    public MyTimer(TimerCallback timerCallBack, int period = System.Threading.Timeout.Infinite,
        int dueTime = System.Threading.Timeout.Infinite, object _state = null)
    {
        this._period = period;
        this._dueTime = dueTime;
        _timer = new System.Threading.Timer(timerCallBack, _state, dueTime, period);
    }

    public void Start(int period = 0)
    {
        if (_timer != null)
        {
            if (period != 0)
            {
                _period = period;
            }
            _timer.Change(_dueTime, _period);
        }
    }

    public void Stop()
    {
        _timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
    }

    public void Change(int dueTime, int period)
    {
        if (dueTime!= System.Threading.Timeout.Infinite)
        {
            _dueTime = dueTime;
        }
        if (period != System.Threading.Timeout.Infinite)
        {
            _period = period;
        }
        _timer.Change(_dueTime, _period);
    }

    public void Period(int period)
    {
        if (period >= 0)
        {
            _period = period;
        }
    }

    public void DueTime(int dueTime)
    {
        if (dueTime >= 0)
        {
            _dueTime = dueTime;
        }
    }

    public void Dispose()
    {
        _timer = null;
    }
}

class test
{
    private MyTimer _timer = new MyTimer(TimerCallBack, 1, 0, null);

    void TimerCallBack(object state)
    {
        //Do something
    }
}
2

2 Answers

1
votes

All you need to do is move the initialization of the _timer object into a constructor, like this:

class test
{
    private MyTimer _timer; // Removed field initializer.

    // Added constructor.
    internal test()
    {
        // Moved initialization of _timer into constructor.
        _timer = new MyTimer(TimerCallBack, 1, 0, null);
    }

    void TimerCallBack(object state)
    {
        //Do something
    }
}

The error is indicating that a field initializer can't use a non-static member (in this case, your TimerCallBack method). Field initializers run before constructors, so there would be no way a field initializer could use an instance member (i.e. the TimerCallBack method) before the instance is constructed.

0
votes

Just dont use TimerCallback at all!

You can define a delegate like here:

    public class MyClass
    {
        public delegate void callableMethod();
        callableMethod outsideMethod;

        public MyClass(callableMethod usersMethod)
        {
            outsideMethod = usersMethod;
        }
    }

And then you can call it like this somewhere in MyClass:

outsideMethod();