C#每秒运行一个函数的最佳方法,定时器与线程?
C# Best Way to run a function every second, Timer vs Thread?
我目前在控制台应用程序中使用一个线程 运行 每秒执行一个函数 C# 是线程的最佳方式吗?正如我问过很多朋友,他们建议使用计时器而不是线程来 运行 每秒执行一些操作?如果使用计时器是更好的选择,我将如何使用计时器每秒 运行 执行一个函数?我环顾四周,但我真的不确定这是否适用,以及以我自己的方式处理它是否正确。那么有人可以告诉我答案以及我该怎么做吗?
那么每秒 运行 它的最佳方法是什么?在你回答之前,让我告诉你,这是 运行 每秒 运行ning 大约 2 天...
我目前的线程编码
namespace Reality.Game.Misc
{
using Reality;
using Reality.Communication.Outgoing;
using Reality.Game.Rooms;
using Reality.Game.Sessions;
using Reality.Storage;
using System;
using System.Data;
using System.Threading;
public static class JobCacheWorker
{
private static Thread jWorkerThread;
public static void HandleExpiration(Session Session)
{
using (SqlDatabaseClient client = SqlDatabaseManager.GetClient())
{
Session.CharacterInfo.UpdateWorking(client, 0);
}
}
public static void Initialize()
{
jWorkerThread = new Thread(new ThreadStart(JobCacheWorker.ProcessThread));
jWorkerThread.Priority = ThreadPriority.Highest;
jWorkerThread.Name = "JobCacheWorker";
jWorkerThread.Start();
}
public static void CheckEffectExpiry(Session Session)
{
try
{
//RunMyCodeHere...
}
catch (Exception exception)
{
Console.WriteLine("Exception - JobCacheWorker -> " + exception.Message);
}
}
private static void ProcessThread()
{
while (Program.Alive)
{
try
{
foreach (Session Session in SessionManager.Sessions.Values)
{
if (Session != null && Session.Authenticated && !Session.Stopped)
{
CheckEffectExpiry(Session);
Thread.Sleep(1000);
}
}
}
catch (ThreadAbortException exception)
{
Output.WriteLine("ThreadAbortException - JobCacheWorker -> " + exception.Message);
}
catch (ThreadInterruptedException exception2)
{
Output.WriteLine("ThreadInterruptedException - JobCacheWorker -> " + exception2.Message);
}
}
}
}
}
如果您希望任务 运行 与任何当前任务并行,那么使用线程是个不错的选择。虽然,由于任务是每秒发生一次,我认为这是一个非常小的任务。在那种情况下,最好使用计时器,因为代码更少且更容易理解。
为此,您可以参考系统Timer class。它有一个例子和一切。
但总的来说,这些是您要做的事情:
- 创建一个定时器的实例(最好全局声明并在Initialize()中初始化)
- 设置间隔(1秒=1000毫秒)
- 启用定时器
- 开始吧
- 可选,您甚至可以根据需要停止它
我会使用 System.Threading.Timer
,因为它通常比专用线程使用更少的资源。这是一个例子:
using System;
using System.Threading;
namespace Demo
{
public static class Program
{
public static void Main()
{
Console.WriteLine("Starting timer with callback every 1 second.");
Timer timer = new Timer(callback, "Some state", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
Thread.Sleep(4500); // Wait a bit over 4 seconds.
Console.WriteLine("Changing timer to callback every 2 seconds.");
timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
Thread.Sleep(9000);
timer.Change(-1, -1); // Stop the timer from running.
Console.WriteLine("Done. Press ENTER");
Console.ReadLine();
}
private static void callback(object state)
{
Console.WriteLine("Called back with state = " + state);
}
}
}
这是控制台应用程序的不错选择。但是,您当然必须记住,回调仍在与主线程分开的线程上完成,因此您必须小心同步回调和主线程之间共享的资源和变量。
您可以查看 System.Threading.Timer,它定期在线程池上执行单个回调,这使其比线程更准确。
这里你的代码看起来像
static void Main(string[] args)
{
TimerCallback tmCallback = CheckEffectExpiry;
Timer timer = new Timer(tmCallback,"test",1000,1000);
Console.WriteLine("Press any key to exit the sample");
Console.ReadLine();
}
static void CheckEffectExpiry(object objectInfo)
{
//TODO put your code
}
我目前在控制台应用程序中使用一个线程 运行 每秒执行一个函数 C# 是线程的最佳方式吗?正如我问过很多朋友,他们建议使用计时器而不是线程来 运行 每秒执行一些操作?如果使用计时器是更好的选择,我将如何使用计时器每秒 运行 执行一个函数?我环顾四周,但我真的不确定这是否适用,以及以我自己的方式处理它是否正确。那么有人可以告诉我答案以及我该怎么做吗?
那么每秒 运行 它的最佳方法是什么?在你回答之前,让我告诉你,这是 运行 每秒 运行ning 大约 2 天... 我目前的线程编码
namespace Reality.Game.Misc
{
using Reality;
using Reality.Communication.Outgoing;
using Reality.Game.Rooms;
using Reality.Game.Sessions;
using Reality.Storage;
using System;
using System.Data;
using System.Threading;
public static class JobCacheWorker
{
private static Thread jWorkerThread;
public static void HandleExpiration(Session Session)
{
using (SqlDatabaseClient client = SqlDatabaseManager.GetClient())
{
Session.CharacterInfo.UpdateWorking(client, 0);
}
}
public static void Initialize()
{
jWorkerThread = new Thread(new ThreadStart(JobCacheWorker.ProcessThread));
jWorkerThread.Priority = ThreadPriority.Highest;
jWorkerThread.Name = "JobCacheWorker";
jWorkerThread.Start();
}
public static void CheckEffectExpiry(Session Session)
{
try
{
//RunMyCodeHere...
}
catch (Exception exception)
{
Console.WriteLine("Exception - JobCacheWorker -> " + exception.Message);
}
}
private static void ProcessThread()
{
while (Program.Alive)
{
try
{
foreach (Session Session in SessionManager.Sessions.Values)
{
if (Session != null && Session.Authenticated && !Session.Stopped)
{
CheckEffectExpiry(Session);
Thread.Sleep(1000);
}
}
}
catch (ThreadAbortException exception)
{
Output.WriteLine("ThreadAbortException - JobCacheWorker -> " + exception.Message);
}
catch (ThreadInterruptedException exception2)
{
Output.WriteLine("ThreadInterruptedException - JobCacheWorker -> " + exception2.Message);
}
}
}
}
}
如果您希望任务 运行 与任何当前任务并行,那么使用线程是个不错的选择。虽然,由于任务是每秒发生一次,我认为这是一个非常小的任务。在那种情况下,最好使用计时器,因为代码更少且更容易理解。
为此,您可以参考系统Timer class。它有一个例子和一切。
但总的来说,这些是您要做的事情:
- 创建一个定时器的实例(最好全局声明并在Initialize()中初始化)
- 设置间隔(1秒=1000毫秒)
- 启用定时器
- 开始吧
- 可选,您甚至可以根据需要停止它
我会使用 System.Threading.Timer
,因为它通常比专用线程使用更少的资源。这是一个例子:
using System;
using System.Threading;
namespace Demo
{
public static class Program
{
public static void Main()
{
Console.WriteLine("Starting timer with callback every 1 second.");
Timer timer = new Timer(callback, "Some state", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
Thread.Sleep(4500); // Wait a bit over 4 seconds.
Console.WriteLine("Changing timer to callback every 2 seconds.");
timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
Thread.Sleep(9000);
timer.Change(-1, -1); // Stop the timer from running.
Console.WriteLine("Done. Press ENTER");
Console.ReadLine();
}
private static void callback(object state)
{
Console.WriteLine("Called back with state = " + state);
}
}
}
这是控制台应用程序的不错选择。但是,您当然必须记住,回调仍在与主线程分开的线程上完成,因此您必须小心同步回调和主线程之间共享的资源和变量。
您可以查看 System.Threading.Timer,它定期在线程池上执行单个回调,这使其比线程更准确。 这里你的代码看起来像
static void Main(string[] args)
{
TimerCallback tmCallback = CheckEffectExpiry;
Timer timer = new Timer(tmCallback,"test",1000,1000);
Console.WriteLine("Press any key to exit the sample");
Console.ReadLine();
}
static void CheckEffectExpiry(object objectInfo)
{
//TODO put your code
}