【问题标题】:C# - Timer ran by the callback of a thread only runs onceC# - 由线程回调运行的定时器只运行一次
【发布时间】:2018-11-04 11:59:44
【问题描述】:

因此,在我正在处理的 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() 函数只从 startSpectating() 函数上的计时器运行一次,我不完全确定为什么。有任何想法吗?不知道这篇文章是否有意义,所以如果我需要进一步扩展,请告诉我,谢谢!

【问题讨论】:

  • Timer 构造函数的第 4 个参数指定 周期,即滴答之间的延迟。你让它无限,所以正确地观察到你有“只运行一次”的行为。然后,您通过反复重新创建计时器对象来解决它,但在 startSpectating() 中摸索了一个。 System.Threading.Timer 非常棘手,垃圾收集可以让它在没有看到对对象的引用时停止滴答作响。 Fwiw,使用它的 Change() 方法是确保它保持活动状态的一种方法。但不要使用 Infinite 来取得成功。

标签: c#


【解决方案1】:

startSpectating 方法中,您没有重新分配静态timer 字段。相反,您在该方法内创建一个新变量timer,该变量在方法存在并且变量失去作用域后符合垃圾回收条件。您可能打算像在其他方法中一样将新计时器分配给静态 field 计时器。如果不创建一个新字段并为其分配新的计时器。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 2017-11-05
    • 2017-04-14
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多