0

我正在 ASP.NET 环境中使用 SignalR 构建具有多个小部件的实时仪表板。在所有小部件都加载了它们的默认数据后,每个小部件都需要独立更新其数据。这意味着我正在使用多个计时器来更新他们的数据,这些数据来自数据库。

现在我的问题是在上述情况下使用计时器的最佳方法是什么,以及如何确保它是线程安全的

这是我现在使用的代码:

public static void Init(){      

    Stopwatch.Start();

    _timer = new Timer(_ =>
    {
        if (_updating)
        {
            return;
        }
        _updating = true;

        try
        {
            var timeDiffSecs = Stopwatch.Elapsed.TotalSeconds;
            Stopwatch.Restart();

            if (timeDiffSecs <= 0)
            {
                return;
            }

            //DoMyActionForUpdate
        }
        finally
        {
            _updating = false;
        }
    }, null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
}
4

1 回答 1

1

两者都使用线程池线程调用事件System.Timers.Timer和回调(分别)。(您没有详细说明您正在使用哪个)这意味着它将(或至少可能)在与任何其他计时器不同的线程上运行。这就像您启动多个线程一样——您需要使这些例程成为线程安全的。System.Threading.TimerElapsed

不管这些线程是如何开始的,技术都是一样的。任何可以在不能原子访问的线程之间共享的数据都需要与其他线程同步。这通常使用lock关键字来完成。您没有提供任何似乎使用任何共享数据的代码;但是,您确实提到了对数据库的访问。如果您有与数据库的共享连接,则必须确保一次只有一个线程使用该连接。例如:

lock(locker)
{
        SqlCommand command = new SqlCommand(queryString, connection);
        command.ExecuteNonQuery();}
}

这显示了一个名为“locker”的字段的使用。您需要创建这个(只是一个Object)并在所有正在运行的线程中共享它。

如果您提供有关您正在做的事情的更多详细信息,特别是;有人可能能够提供更详细的答案。

于 2012-08-11T15:51:31.927 回答