您好,有人可以在Accurate Timer类中为我提供帮助吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("AccuTimer Test......");
new Thread(delegate () {
var a = new RunInTreadUseAccutimer(500, 0, "AccuTimer 1");
}).Start();
new Thread(delegate () {
var b = new RunInTreadUseAccutimer(5000, 4900, "AccuTimer 2");
}).Start();
new Thread(delegate () {
var c = new RunInTreadUseTreadSleep(500, "Thread Sleep 1");
}).Start();
new Thread(delegate () {
var d = new RunInTreadUseTreadSleep(5000, "Thread Sleep 2");
}).Start();
Console.Read();
}
}
public class RunInTreadUseAccutimer
{
private readonly int _interval;
private readonly int _interval2;
private readonly string _name;
private AccuTimer _timer;
public RunInTreadUseAccutimer(int interval, int interval2, string name)
{
_interval = interval;
_interval2 = interval2;
_name = name;
_timer = new AccuTimer(this, "Go", _interval);
}
public void Go()
{
Console.WriteLine($"{DateTime.UtcNow:ddd d MMM yyyy HH:mm:ss.ffff} - Name: {_name} - Interval: {_interval}");
Thread.Sleep(_interval2);
}
}
public class RunInTreadUseTreadSleep
{
private readonly int _interval;
private readonly string _name;
public RunInTreadUseTreadSleep(int interval, string name)
{
_interval = interval;
_name = name;
Go();
}
public void Go()
{
while (true)
{
Thread.Sleep(_interval);
Console.WriteLine($"{DateTime.UtcNow:ddd d MMM yyyy HH:mm:ss.ffff} - Name: {_name} - Interval: {_interval}");
}
}
}
public class AccuTimer
{
private delegate void TimerEventDel(int id, int msg, IntPtr user, int dw1, int dw2);
private const int TIME_PERIODIC = 1;
private const int EVENT_TYPE = TIME_PERIODIC;// + 0x100; // TIME_KILL_SYNCHRONOUS causes a hang ?!
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeSetEvent(int delay, int resolution, TimerEventDel handler, IntPtr user, int eventType);
[DllImport("winmm.dll")]
private static extern int timeKillEvent(int id);
private readonly string _method;
private readonly int _accuTimerId;
private readonly dynamic _className;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly TimerEventDel _accuHandler; // NOTE: declare at class scope so garbage collector doesn't release it!!!
public AccuTimer(dynamic className, string method, int delay)
{
_method = method;
_className = className;
timeBeginPeriod(1);
_accuHandler = new TimerEventDel(TimerCallback);
_accuTimerId = timeSetEvent(delay, 0, _accuHandler, IntPtr.Zero, EVENT_TYPE);
}
public void Stop()
{
int err = timeKillEvent(_accuTimerId);
timeEndPeriod(1);
Thread.Sleep(100);// Ensure callbacks are drained
}
private void TimerCallback(int id, int msg, IntPtr user, int dw1, int dw2)
{
if (_accuTimerId != 0)
{
var methodInfo = _className.GetType().GetMethod(_method);
if (methodInfo != null)
methodInfo.Invoke(_className, null);
}
}
}
}
我在这里找到了毫秒级的精确计时器:Most accurate timer in .NET?关于Stackoverflow,我对此计时器的精确度和性能感到非常满意。但是当我尝试在不同线程中同时使用两个计时器时,我现在遇到了问题。如果我阻塞了其中一个踏板,则它将阻塞另一个线程上的计时器。...如果您运行上述程序,则会被破坏...
我如何修改此类以适应踩踏/线程安全?