gpt4 book ai didi

c# - 如何防止 System.Timers.Timer 在线程池上排队执行?

转载 作者:可可西里 更新时间:2023-11-01 08:34:22 24 4
gpt4 key购买 nike

标准 System.Timers.Timer 行为存在问题。计时器以一定间隔引发 Elapsed 事件。但是当 Elapsed 事件处理程序中的执行时间超过计时器间隔时,线程池开始排队处理事件。这是我的问题。这是因为我使用 Elapsed 事件处理程序从数据库中获取一些数据并对其进行处理,最后将结果保存回数据库。但是数据处理应该只提供一次。那么,有没有一种方法可以防止对 System.Timers.Timer 的经过事件进行排队。

作为此问题的说明,您可以考虑下一个测试程序:

public class EntryPoint
{

private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
}

static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
System.Timers.Timer MyTimer = new System.Timers.Timer(1000);
MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Start();
Console.ReadLine();
MyTimer.Stop();
}
}

可能的输出如下:

Current time 03.02.2011 0:00:09 on the thread 4
Current time 03.02.2011 0:00:10 on the thread 5
Current time 03.02.2011 0:00:12 on the thread 6
Current time 03.02.2011 0:00:13 on the thread 7
Current time 03.02.2011 0:00:14 on the thread 8
Current time 03.02.2011 0:00:15 on the thread 9
Current time 03.02.2011 0:00:16 on the thread 10
Current time 03.02.2011 0:00:17 on the thread 11
Current time 03.02.2011 0:00:18 on the thread 12
Current time 03.02.2011 0:00:19 on the thread 13
Current time 03.02.2011 0:00:30 on the thread 4
Current time 03.02.2011 0:00:30 on the thread 5

可能的解决方案:

1) 灵感来自:C# Timer vs Thread in Service

并且有一个关于上述示例的代码:

    public class EntryPoint
{
private static System.Timers.Timer MyTimer;
private static void TimeProc(object state, ElapsedEventArgs e)
{
Console.WriteLine("Current time {0} on the thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
MyTimer.Enabled = true;
}

static void Main(string[] args)
{
Console.WriteLine("Press <Enter> for finishing\n\n");
ThreadPool.SetMaxThreads(10, 10);
MyTimer = new System.Timers.Timer(1000);
MyTimer.AutoReset = false;

MyTimer.Elapsed += new ElapsedEventHandler(TimeProc);
MyTimer.Enabled = true;
Console.ReadLine();

}
}

2) 第二种方法是关于 SynchronizingObject,但它仅对 Windows 窗体应用程序有值(value),或者需要额外开发代码来实现将实现 ISynchronizeInvoke 接口(interface)的对象。关于这种方式的更多信息,您可以找到 here

所以,现在我更喜欢第一种解决方案。

最佳答案

在这种情况下,我通常做的是在 Elapsed 处理程序开始时停止计时器,并在结束时再次启动它。这样,您一次只处理一个订单号。

更新:

根据 MSDN 链接,我认为他们的意思是您可以设置自己的标志(但仍然有滴答声),但也应采取线程安全措施。

关于c# - 如何防止 System.Timers.Timer 在线程池上排队执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4876414/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com