C# Thread.Sleep() _PC 之间执行的其他时间
Posted
技术标签:
【中文标题】C# Thread.Sleep() _PC 之间执行的其他时间【英文标题】:C# Thread.Sleep() _ Other time to perform between PCs 【发布时间】:2021-05-08 11:03:35 【问题描述】:我有一个问题。
下面的源码是按下按钮时面板左右移动的线程。
但是,如果在开发 PC 上移动大约 1 秒,则在测试 PC 上大约需要 4 秒。
*测试 PC 的硬件性能更好。
我想知道为什么会出现这些结果。
private void move()
while (Moving)
SlidePanel.BeginInvoke(new Action(() =>
if (SlideDirection == 0) // Left
SlidePanel.Left -= 4;
if (SlidePanel.Left <= SystemSettingbtn.Left)
SlidePanel.Left = SystemSettingbtn.Left;
SystemPanel.BeginInvoke(new Action(() =>
SystemPanel.BringToFront();
));
Moving = false;
else // Right
SlidePanel.Left += 4;
if (SlidePanel.Left >= EnvSettingbtn.Left)
SlidePanel.Left = EnvSettingbtn.Left;
EnvironmnetPanel.BeginInvoke(new Action(() =>
EnvironmnetPanel.BringToFront();
));
Moving = false;
));
Thread.Sleep(1);
使用 [await Task.With Daly (1)]
我已经确认两种环境具有相同的运行时间。
感觉很奇怪 Thread.sleep(1) 在更好的环境中变慢了。
【问题讨论】:
可以发Moving
的声明吗?
@Zer0 我从线程中声明了布尔值。 [bool Moving = false] 和当按钮事件发生时改变 Moving = true -> 线程开始
【参考方案1】:
这不是线程安全的。您需要以某种方式同步Moving
。最简单的方法是使用lock
。
有更有效的方法,但从这里开始学习是您最安全的选择。像这样的东西。
private readonly object movingLock = new object();
private bool _moving;
private bool Moving
get lock (movingLock) return _moving
set lock (movingLock) _moving = value;
关于为什么需要这样做的重要说明。 if (_moving)
不同步可以返回旧值。
您可以在这里使用volatile
,但与流行的观点相反,它仍然不能保证读取到最新的值。
由于Thread.Sleep(1)
,您会看到差异。由内核来处理线程调度。它不保证那个时间。
我也不明白你为什么要在 UI 线程上执行 BeginInvoke
。可以使用Control.InvokeRequired
查看。
如果您 BeginInvoke
已经在 UI 线程上会发生什么?
它不会立即执行。它被放置在消息队列中。该队列的大小也会增加显着的差异。
绘制消息在队列中的优先级较低。如果有要处理的消息会改变绘画,为什么还要费心绘画呢?所以这也会延迟绘画。
【讨论】:
您能否提供一个权威来源,为什么 volatile 不能解决这个问题?无论哪种方式,我都阅读过意见,但没有看到有关问题细节的良好来源。 @JonasH volatile 真正的意思是告诉编译器“不要优化这个”,因为许多编译器优化包括读写重新排序。这是一个深入的source。我不会称任何来源为“权威”,包括我自己。 您提供的链接表示,如果架构需要,访问 volatile 字段将发出栅栏。并且围栏应该足以确保该值是最新的。 IE。栅栏影响编译器和 CPU。所以我仍然不明白为什么 volatile 还不够。 @JonasH 不,它没有。我建议阅读整个页面。引用:“...文档指出,使用 volatile 关键字可确保该字段始终存在最新的值。这是不正确的...” Joe Duffy 编写了示例代码(他曾在Microsoft,写了一本关于并发的书,并且是 TPL 的领导者)。 对于那些想要像volatile
这样易于使用而没有陷阱的人,只需使用Thread.VolatileRead
(和VolatileWrite
)代替。以上是关于C# Thread.Sleep() _PC 之间执行的其他时间的主要内容,如果未能解决你的问题,请参考以下文章
C# Task.Delay()和Thread.Sleep()有什么区别?
C#中的Task.Delay()和Thread.Sleep()区别