我正在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));
}
答案 0 :(得分:1)
System.Timers.Timer
和System.Threading.Timer
都使用线程池线程调用Elapsed
事件和回调(分别)。 (你还没有详细说明你正在使用哪一个)这意味着它将(或至少可能)运行在与任何其他计时器不同的线程上。这与启动多个线程相同 - 您需要使这些例程成为线程安全的。
无论这些线程如何开始,技术都是一样的。可以在不可原子访问的线程之间共享的任何数据都需要与其他线程同步。这通常使用lock
关键字来完成。您没有提供任何似乎使用任何共享数据的代码;但是,您确实提到了对数据库的访问权限。如果您有与数据库的共享连接,则必须确保一次只有一个线程使用该连接。例如:
lock(locker)
{
SqlCommand command = new SqlCommand(queryString, connection);
command.ExecuteNonQuery();}
}
这显示了名为“locker”的字段的使用。你需要创建它(只是一个Object
)并在游戏的所有线程中共享它。
如果你提供更多关于你正在做什么的细节,特别是;有人可能会提供更详细的答案。