System.Timer.Timer的lock争用问题
//辅助类
static class Common
{
//圆心
public static Point CenterPoint = new Point(25, 25);
//包围矩形
public static Rectangle Rect = new Rectangle(0, 0, 50, 50);
//绘图委托
public delegate void DrawDelegate();
//最慢速临界角度
public const int slowAngle_1 = 315;
public const int slowAngle_2 = 135;
//最快速临界角度
public const int quickAngle_1 = slowAngle_1 + 90 - 360;
public const int quickAngle_2 = slowAngle_2 + 90;
/// <summary>
/// 根据半径、角度求圆上坐标
/// </summary>
/// <param name="radius">半径</param>
/// <param name="angle">角度</param>
/// <returns>坐标</returns>
public static Point GetDotLocationByAngle(int radius, int angle)
{
int x, y;
x = (int)(CenterPoint.X + radius * Math.Cos(angle * Math.PI / 180));
y = (int)(CenterPoint.Y + radius * Math.Sin(angle * Math.PI / 180));
return new Point(x, y);
}
}
//窗体类
public partial class Form1 : Form
{
Dot[] dots = new Dot[5];
//当前活动点索引(用于辅助支持线程同步)
//public static int CurrentDotIndex = 0;
//public static object lockobj = new object();
public Form1()
{
InitializeComponent();
for (int i = 0; i < dots.Length; ++i)
{
dots[i] = new Dot(i, this.CreateGraphics());
}
}
/// <summary>
/// 变更活动点
/// </summary>
//public static void NextDot()
//{
// lock (lockobj)
// {
// if (CurrentDotIndex < 4)
// ++CurrentDotIndex;
// else
// CurrentDotIndex = 0;
// }
//}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < dots.Length; ++i)
{
dots[i].Start();
}
}
}//end of class Form1
/// <summary>
/// 表示一个“点”
/// </summary>
internal sealed class Dot
{
readonly int m_index;
/// <summary>
/// 点位于点数组中的索引(0~4)
/// </summary>
public int Index
{
get { return m_index; }
}
bool m_isVisible;
/// <summary>
/// 是否可见
/// </summary>
public bool IsVisible
{
get { return m_isVisible; }
set { m_isVisible = value; }
}
//点坐标
Point m_location;
//角度
int m_angle;
//定时器
System.Timers.Timer m_tmr;
//图形
Graphics m_graphics;
/// <summary>
/// 构造点
/// </summary>
/// <param name="index">点位于点数组中的索引(0~4)</param>
/// <param name="g">图形</param>
public Dot(int index, Graphics g)
{
if (index < 0 || index > 4)
throw new IndexOutOfRangeException("索引必须在0~4之间");
m_index = index;
m_isVisible = false;
m_tmr = new System.Timers.Timer(30);
m_tmr.Elapsed += m_tmr_Elapsed;
m_graphics = g;
m_angle = 312 - m_index * 12;
}
void m_tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//if (this.InvokeRequired)
//{
// DrawDelegate draw = Draw;
// this.BeginInvoke(draw);
//}
Console.WriteLine(m_tmr.Interval);
//if (Form1.CurrentDotIndex == m_index)
//{
//Common.DrawDelegate drawdele = Draw;
//drawdele();
Draw();
m_angle = m_angle >= 356 ? 0 : m_angle + 4;
#region ChangeTimerInterval
if (m_angle >= Common.slowAngle_1 || m_angle < Common.quickAngle_1)//因涉及到359变0,此处为||而不是&&
{
if (m_tmr.Interval > 2)
{
m_tmr.Interval -= 2;
}
else if (m_tmr.Interval > 0.1)
{
m_tmr.Interval -= 0.1;
}
else if (m_tmr.Interval > 0.01)
{
m_tmr.Interval -= 0.01;
}
else if (m_tmr.Interval > 0.001)
{
m_tmr.Interval -= 0.001;
}
}
else if (m_angle >= Common.quickAngle_1 && m_angle < Common.slowAngle_2)
{
if (m_tmr.Interval < 30)
{
++m_tmr.Interval;
}
}
else if (m_angle >= Common.slowAngle_2 && m_angle < Common.quickAngle_2)
{
if (m_tmr.Interval > 2)
{
m_tmr.Interval -= 2;
}
else if (m_tmr.Interval > 0.1)
{
m_tmr.Interval -= 0.1;
}
else if (m_tmr.Interval > 0.01)
{
m_tmr.Interval -= 0.01;
}
else if (m_tmr.Interval > 0.001)
{
m_tmr.Interval -= 0.001;
}
}
else if (m_angle >= Common.quickAngle_2 && m_angle < Common.slowAngle_1)
{
if (m_tmr.Interval < 30)
{
++m_tmr.Interval;
}
}
#endregion
// Form1.NextDot();
//}
}
public void Start()
{
if (!m_tmr.Enabled)
m_tmr.Start();
}
public void Stop()
{
if (m_tmr.Enabled)
m_tmr.Stop();
}
/// <summary>
/// 绘制
/// </summary>
private void Draw()
{
lock (m_graphics)
{
Rectangle rect = new Rectangle(m_location, new Size(3, 3));
//m_graphics.DrawEllipse(Pens.RoyalBlue, rect);
m_graphics.FillEllipse(Brushes.RoyalBlue, rect);//Erase last frame
m_location = Common.GetDotLocationByAngle(25, m_angle);
rect = new Rectangle(m_location, new Size(3, 3));
m_graphics.FillEllipse(Brushes.White, rect);
}
}
}//end of class Dot
我用一个Dot对象表示一个“点”,每个Dot有自己的timer,但共用一个由窗体创建的Graphics,线程争用问题导致点的顺序会乱,求各位大神给个解决方案……万谢……
PS:各位大神可以新建个winform运行下,错位在转一圈之后就很明显了
相关推荐
C# Timer深度解析:从基础使用到高级调度实战指南
定时任务调度是软件开发中的核心概念,它允许程序在特定时间或周期性地执行代码逻辑。其原理通常基于操作系统或运行时提供的计时器机制,通过回调函数或事件驱动模型触发预定操作。在C#生态中,这一技术价值体现在构建可靠的后台服务、实现自动化作业以及优化资源管理等方面。无论是桌面应用的UI更新、服务器端的数据处理,还是游戏中的冷却计时,精准的调度都至关重要。本文聚焦于C#中多种Timer类的选择与避坑,特别是针对**System.Threading.Timer**和**System.Timers.Timer**的线程模
C#高精度计时器与System.Threading.Timer应用指南
在软件开发中,计时器是实现任务调度和时间控制的核心组件。System.Threading.Timer作为.NET框架中的轻量级计时器,采用线程池机制执行回调,避免了UI线程阻塞问题。其底层原理基于系统时钟中断,典型精度为15毫秒,适用于后台任务处理等场景。对于更高精度需求,可结合Stopwatch类实现微秒级测量,或使用自旋等待技术达到纳秒级延迟控制。这些技术在实时数据采集、游戏开发、金融交易等对时间敏感的应用中尤为重要。通过合理的线程优先级设置和误差补偿算法,开发者可以构建出高稳定性的定时任务系统。
上位机定时器设计:多Timer任务拆分与最佳实践
定时器是编程中常用的时间触发机制,用于在指定间隔执行任务。在上位机开发中,定时器设计直接影响系统稳定性与响应速度。如果所有任务共用一个定时器,容易出现界面卡顿、数据丢帧、任务互相干扰等问题。通过理解不同定时器(如System.Windows.Forms.Timer、System.Timers.Timer)的适用场景,按任务频率拆分定时器、为回调设置时间预算、使用标志位防止重入,可构建高效的任务调度方案。C# WinForms/WPF环境下,结合状态机与队列模型,能进一步优化多任务处理。本文从基础概念出发,分
正交拉丁超立方(OLHC)分组与实验设计(DOE)评估的优化Python实现.rar
正交拉丁超立方(OLHC)分组与实验设计(DOE)评估的优化Python实现.rar
Java微服务如何拆解审计日志查询服务
标题:Java微服务如何拆解审计日志查询服务 内容概要:围绕缓存策略、任务调度、回压控制和审计追踪,拆解Java微服务如何拆解审计日志查询服务的实现细节。 xdronline.com xdrea.com 9g.xinmei6.com xinghaohuanbao.com m.xiker66.com


