C#-线程回调运行的计时器只运行一次

C#-线程回调运行的计时器只运行一次,c#,C#,因此,我在一个C#应用程序中遇到了一个线程和计时器的小问题,其中一个关键计时器只运行一次 这是启动初始线程的程序的主要功能: private static System.Threading.Timer timer; static void Main(string[] args) { timer = new System.Threading.Timer(_ => startAutoSpec(), null, 1000 * 5, Timeout.Infinite); } 此后,在

因此,我在一个C#应用程序中遇到了一个线程和计时器的小问题,其中一个关键计时器只运行一次

这是启动初始线程的程序的主要功能:

private static System.Threading.Timer timer;

static void Main(string[] args) 
{
    timer = new System.Threading.Timer(_ => startAutoSpec(), null, 1000 * 5, Timeout.Infinite);
}
此后,在startAutoSpec(如下)函数中,它运行整个代码(我认为没有任何添加的必要),并且出于所有目的,它运行得非常好

public static void startAutoSpec() 
{
    if (noGamesFound) {
        timer.Dispose();
        timer = new System.Threading.Timer(_ => startAutoSpec(), null, 1000 * 60, Timeout.Infinite);
    } else 
    { 
        startSpectating(args here);
        timer.Dispose();
    }
}
现在我们遇到了主要问题,计时器在startSpectating函数中初始化。它似乎只运行一次

public static void startSpectating(whatever args) 
{
    all the spectating related stuff
    var timer = new System.Threading.Timer((e) =>
    {
        stillInGame(summoner.id.ToString(), region, gameid.ToString());
    }, null, startTimeSpan, periodTimeSpan);
}
然后运行这个检查器

public static void stillInGame(string sumId, string region, string gameId)
{
    checks that game is still active
    Console.WriteLine("Checking if still ingame...");
    if (game is finished) {
        close the game process
        timer = new System.Threading.Timer(_ => startAutoSpec(), null, 1000 * 60, Timeout.Infinite);
    }
}

因此,我认为我需要提供线程和计时器如何工作的整个上下文,以最好地描述我的问题。stillInGame()函数只从StartSpecting()函数的计时器运行一次,我不完全确定原因。有什么想法吗?我也不确定这篇文章是否有意义,所以如果我需要进一步扩展,请告诉我,谢谢

在方法
startspecting
中,您没有重新分配静态
计时器
字段。相反,您正在该方法内创建一个新变量
timer
,该变量在该方法存在且该变量失去作用域后有资格进行垃圾收集。您可能想像在其他方法中一样,将新计时器分配给静态
字段
计时器。如果没有,则创建一个新字段并为其分配新计时器

public static void startSpectating(whatever args) 
{
    var timer = new System.Threading.Timer((e) => ....
    // should be
    timer = new System.Threading.Timer((e) => ....

计时器构造函数的第四个参数指定周期,即滴答之间的延迟。您将其设置为无限,因此正确地观察到了“仅运行一次”行为。然后,您通过反复重新创建计时器对象来解决这个问题,但在startSpecting()中摸索了一个。Timer是相当棘手的,垃圾收集可以使它在看到没有对象引用时停止滴答声。Fwiw,使用其Change()方法是确保它在一个刻度内保持活动的一种方法。但不要用无限来获得成功。