无法更改在使用块中声明的计时器



我想声明使用A的计时器,以利用自动处置。但是我希望计时器更改自己的间隔,以确保在回调仍在运行

时不会打勾

问题是我无法从回调内引用计时器。

string s = "sample object";
using (Timer t = new Timer(
    state =>
    {
        var nextTime = DateTime.Now.AddMilliseconds(interval);
        // do work on object in method scope, so thought to declare timer callback here
        var x = s;
        // but timer callback should call Change on itself
        t.Change(Math.Max(nextTime.Subtract(DateTime.Now).Milliseconds, 100), Timeout.Infinite);
        // ^^^ Use of unassigned local variable 't'
    }, null, interval, Timeout.Infinite))
{
    var finishTime = DateTime.Now.AddSeconds(10);
    while (finishTime > DateTime.Now)
    {
        Thread.Sleep(333);
        Console.WriteLine($"{(finishTime - DateTime.Now).TotalSeconds} remaining.");
    }
}

以下语法允许我从回调内更改计时器,但是我失去了第一个示例的范围(无法访问对象o(,并且在使用中没有声明。

private static Timer s = new Timer(new TimerCallback(c), null, 1000, Timeout.Infinite);
private static void c(object state)
{
    s.Change(1000, Timeout.Infinite);
}

有什么方法可以解决吗?我正在尝试访问与计时器一起定义的本地变量,并将其声明为使用块。

您可以做一些黑客 - 您可以在using之前声明Timer t = null

这将导致使用"修改后的闭合",但是尽管它实际上有效:

using System;
using System.Threading;
namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            int interval = 1000;
            string s = "sample object";
            Timer t = null;
            using (t = new Timer(
                state =>
                {
                    var nextTime = DateTime.Now.AddMilliseconds(interval);
                    // do work on object in method scope, so thought to declare timer callback here
                    Console.WriteLine("Doing work with " + s);
                    // but timer callback should call Change on itself
                    t.Change(Math.Max(nextTime.Subtract(DateTime.Now).Milliseconds, 100), Timeout.Infinite);
                }, null, interval, Timeout.Infinite))
            {
                var finishTime = DateTime.Now.AddSeconds(10);
                while (finishTime > DateTime.Now)
                {
                    Thread.Sleep(333);
                    Console.WriteLine($"{(finishTime - DateTime.Now).TotalSeconds} remaining.");
                }
            }
        }
    }
}

但是,整个方法似乎有点狡猾!

我建议您不要这样做 - 找到一种不需要使用计时器的方法(请注意Servy的评论(。

最新更新