Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# System.Threading.Timer在25-30次后停止_C#_Multithreading_Timer - Fatal编程技术网

C# System.Threading.Timer在25-30次后停止

C# System.Threading.Timer在25-30次后停止,c#,multithreading,timer,C#,Multithreading,Timer,在我的C#应用程序中,计时器只工作30次。然后停止。为什么,我不知道。哪里错了 这是我的支票限额助手 var startTimeSpan = TimeSpan.Zero; var periodTimeSpan = TimeSpan.FromSeconds(5); var timer = new System.Threading.Timer((e) => { limit = helper.CheckLi

在我的C#应用程序中,计时器只工作30次。然后停止。为什么,我不知道。哪里错了

这是我的支票限额助手

        var startTimeSpan = TimeSpan.Zero;
        var periodTimeSpan = TimeSpan.FromSeconds(5);

        var timer = new System.Threading.Timer((e) =>
        {
            limit = helper.CheckLimit();
        }, null, startTimeSpan, periodTimeSpan); 

我打赌乔恩的建议是正确的,我将把它抄袭成一个答案

的文档包含以下注释

只要使用计时器,就必须保留对它的引用。与任何托管对象一样,当没有对计时器的引用时,计时器将接受垃圾收集。计时器仍处于活动状态这一事实并不妨碍对其进行收集

var timer
表明您可能没有保持引用处于活动状态。您可以将其设置为对象的字段,该字段在应用程序的整个生命周期内保持活动状态

高级说明
新系统.线程.计时器(TimerCallback回调)
构造函数将
用于
状态
对象,这将使计时器在整个
GC.Collect
过程中保持活动状态(请参阅下文了解更多信息)


例子 下面是一个完整的例子来说明这个问题

输出 代码
浑水
System.Threading.Timer
Timer(TimerCallback回调)
构造函数(不使用
dueTime
和其他构造函数的构造函数)将
用于
状态
,这意味着计时器将保留对自身的引用,这意味着它将在垃圾收集中生存

using System;
using System.Threading.Tasks;

class TimerExperiment
{
    System.Threading.Timer timer; 
    public TimerExperiment() {
        StartTimer("A"); // Not keeping this timer
        timer = StartTimer("B"); // Keeping this timer
    }

    static System.Threading.Timer StartTimer(string name) {
        return new System.Threading.Timer(_ =>
        {
            Console.WriteLine($"{name}");
        }, null, dueTime: TimeSpan.Zero, period: TimeSpan.FromSeconds(1));
    }

}

class Program
{
    static async Task Main(string[] args)
    {
        var withTimers = new TimerExperiment();

        await Task.Delay(TimeSpan.FromSeconds(2));
        GC.Collect();
        Console.WriteLine("GC Collected");
        Console.ReadLine();
    }
}

例2 计时器“C”是使用
Timer(TimerCallback回调)
创建的,它一直在运行

输出 代码
你能分享周围的代码吗?特别是
helper.CheckLimit()
I共享,谢谢。var timer在哪里?在某些方法中?您是否保持对计时器的引用处于活动状态,以确保它未被垃圾收集?从文档中可以看出:只要使用计时器,就必须保留对它的引用。与任何托管对象一样,当没有对计时器的引用时,计时器将接受垃圾收集。计时器仍处于活动状态这一事实并不妨碍对其进行收集。您如何知道计时器已停止工作?您是否有一些代码正在检查以确保实际调用了回调?您能给我一些示例代码吗?因为我是C#的新手,是的,当我回到电脑前,我会破解一些示例代码。
A
B
A
B
B
A
GC Collected
B
B
B
using System;
using System.Threading.Tasks;

class TimerExperiment
{
    System.Threading.Timer timer; 
    public TimerExperiment() {
        StartTimer("A"); // Not keeping this timer
        timer = StartTimer("B"); // Keeping this timer
    }

    static System.Threading.Timer StartTimer(string name) {
        return new System.Threading.Timer(_ =>
        {
            Console.WriteLine($"{name}");
        }, null, dueTime: TimeSpan.Zero, period: TimeSpan.FromSeconds(1));
    }

}

class Program
{
    static async Task Main(string[] args)
    {
        var withTimers = new TimerExperiment();

        await Task.Delay(TimeSpan.FromSeconds(2));
        GC.Collect();
        Console.WriteLine("GC Collected");
        Console.ReadLine();
    }
}

public Timer(TimerCallback callback)
{
    (...)
    TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period, ref stackMark);
}
A
B
C
A
B
C
GC Collected
B
C
C
B
B
C
class TimerExperiment
{
    System.Threading.Timer timerB;

    public TimerExperiment()
    {
        StartTimer("A"); // Not keeping this timer
        timerB = StartTimer("B"); // Keeping this timer
        StartTimer2("C"); // Not keeping this timer
    }

    static System.Threading.Timer StartTimer(string name) {
        return new System.Threading.Timer(_ =>
        {
            Console.WriteLine($"{name}");
        }, null, dueTime: Delay(name), period: TimeSpan.FromSeconds(1));
    }

    static System.Threading.Timer StartTimer2(string name)
    {
        //Create the timer using the constructor which only takes the callback
        var t = new System.Threading.Timer( _ => Console.WriteLine($"{name}"));
        t.Change(dueTime: Delay(name), period: TimeSpan.FromSeconds(1));
        return t;
    }

    static TimeSpan Delay(string name) 
            => TimeSpan.FromMilliseconds(Convert.ToInt64(name[0])*10);

}

class Program
{
    static async Task Main(string[] args)
    {
        var withTimers = new TimerExperiment();

        await Task.Delay(TimeSpan.FromSeconds(2));
        GC.Collect();
        Console.WriteLine("GC Collected");
        Console.ReadLine();
    }
}