将System.Threading.Timer对象引用传递给其回调函数

Are*_*yst 4 .net c# timer

是否可以将System.Threading.Timer对象引用传递给它的回调函数,如下所示:

System.Threading.Timer myTimer = new System.Threading.Timer(new TimerCallback(DoSomething), myTimer, 2000, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)

因为在"DoSomething"方法中我想调用:

myTimer.Change(5000, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)

我将在下面粘贴草稿控制台应用程序.想法是这样的:我有计时器列表.每个计时器都会发出一些请求,当它收到请求时,它会更改一些共享数据.但是,我无法将定时器的引用传递给它的回调,也不能使用它的索引,因为它因某种原因(调查)变为"-1".

using System;
using System.Collections.Generic;
using System.Threading;

namespace TimersInThreads
{
    class Program
    {
        public static int sharedDataInt;
        static private readonly object lockObject = new object();
        public static List<System.Threading.Timer> timers = new List<Timer>();

        static void Main(string[] args)
        {
            System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(DoSomething), timers.Count - 1, 2000, Timeout.Infinite);
            timers.Add(timer);

            System.Threading.Timer timer2 = new System.Threading.Timer(new TimerCallback(DoSomething), timers.Count - 1, 2000, Timeout.Infinite);
            timers.Add(timer2);

            System.Threading.Timer timer3 = new System.Threading.Timer(new TimerCallback(DoSomething), timers.Count - 1, 2000, Timeout.Infinite);
            timers.Add(timer3);

            //timer = new System.Threading.Timer(new TimerCallback(DoSomething), "Timer 1", 1000, Timeout.Infinite);
            //timer = new System.Threading.Timer(new TimerCallback(DoSomething), "Timer 2", 450, Timeout.Infinite);
            //timer = new System.Threading.Timer(new TimerCallback(DoSomething), "Timer 3", 1500, Timeout.Infinite);

            Console.ReadLine();

        }

        static void DoSomething(object timerIndex)
        {
            // Request
            // Get Response
            var x = getSomeNumberWithDelay();


            // Executes after Response is received
            lock (lockObject)
            {
                sharedDataInt++;
                Console.WriteLine("Timer" + (int)timerIndex + ", SHaredDataInt: " + sharedDataInt + "\t\t" + DateTime.Now.ToString("HH:mm:ss tt") + "." + DateTime.Now.Millisecond.ToString());
            }

            timers[(int)timerIndex].Change(5000, Timeout.Infinite);
        }

        static int getSomeNumberWithDelay()
        {
            Thread.Sleep(5000);
            return 3;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请给我一些想法或建议.非常感谢,谢谢!

Jam*_*mes 5

state在参数Timer构造被作为参数传递给TimerCallback-这只是一个object因此将与任何工作,包括定时器引用本身.

所以

new System.Threading.Timer(new TimerCallback(DoSomething), myTimer, 2000, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)

完全可以接受.在您的回调中,您只需要将参数转换为Timer例如

static void DoSomething(object state)
{
    ...
    var timer = (System.Threading.Timer)state;
}
Run Code Online (Sandbox Code Playgroud)

再看一下你的问题,我看到你要做的是将计时器作为参数传递给它的构造函数(显然这是不能完成的,因为它尚未正式声明).您可以通过将计时器显式传递给回调来解决此问题,例如

Timer t = null;
t = new Timer(delegate { DoSomething(t); }, null, 2000, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)

当回调被触发时t将设置为计时器的参考.