我正在尝试创建具有2个线程的应用程序。在主线程中的哪里有一个变量(Int32),我只能从主线程中读取它。
现在,只要程序正在运行,我就有另一个线程循环运行,该线程会创建一个“心跳”,当达到某个点时,我想更新上述变量。该变量仅从该检测信号线程写入,而从其他线程都不写入。
为了保持精度(QueryPerformanceCounter级别),我想避免心跳线程上的任何可能阻塞。
这是简化版:
using System;
using System.Threading;
namespace ConsoleApp2
{
class Program
{
static int Interval = 0;
static void Heartbeat()
{
int counter = 0;
while (counter < 100) {
counter++;
Console.WriteLine($"Heartbeat : {counter}");
if (counter % 10 == 0) {
Interval = counter;
}
Thread.Sleep(100);
}
}
static void Main(string[] args)
{
Thread heartbeat = new Thread(Heartbeat);
heartbeat.Start();
while (Interval < 100) {
Console.WriteLine($"Interval : {Interval}");
Thread.Sleep(100);
}
Console.ReadLine();
}
}
}
它运行了,但是我想知道我的做法是否正确。如果没有,我应该如何改善?
总结:
Interval
仅由主线程读取。Interval
仅由Heartbeat
线程修改。Heartbeat
线程的任何阻塞,最好也不要阻塞主线程。编辑:
我刚刚意识到我正在使用Interval
块来读取Heartbeat()
中的while
,所以我将其从while (Interval < 100)
更改为while (counter < 100)
Edit2:
上面的代码是一个非常简化的版本,实际代码有点混乱,我认为发布所有API部分都不会解决这个问题。
我不需要,只要更新了时间间隔,就不需要主线程来执行某些操作。每个循环更可能只读取一次,如下所示:
int interval;
while (Interval < 100 /* I could use some other condition not invoving Interval */ ) {
interval = Interval;
// all usage of "Interval" from this point would use the value read in interval
Console.WriteLine($"Interval : {interval}");
Thread.Sleep(100);
}
Heartbeat
线程中计算),别无其他,我就可以了。例如,如果在我为该循环读取值时恰好在同一时间更新该值,则可以获取旧值或新值,只要它不是无处不在的无关紧要的值即可。 (如果它读取旧值,它将在下一个循环中读取新值,对吧?)答案 0 :(得分:0)
即使没有阻塞和很短的工作时间,您的计时器线程也会遭受滑移,因为它的工作时间不为0。我认为使用计时器会更好。
请查看Timer Class已在内置的多线程设置中运行。
基于服务器的System.Timers.Timer类设计为与多线程环境中的工作线程一起使用。服务器计时器可以在线程之间移动以处理引发的Elapsed事件,与Windows计时器相比,按时引发事件的准确性更高。
和
如果SynchronizingObject属性为null,则在ThreadPool线程上引发Elapsed事件。如果对Elapsed事件的处理持续时间长于Interval,则该事件可能在另一个ThreadPool线程上再次引发。在这种情况下,事件处理程序应该是可重入的。
最后:
提示
请注意,.NET包含四个名为Timer的类,每个类提供不同的功能:
- System.Timers.Timer (本主题):定期触发事件。该类旨在在多线程环境中用作基于服务器的组件或服务组件。它没有用户界面,并且在运行时不可见。
- System.Threading.Timer :定期在线程池线程上执行单个回调方法。回调方法是在实例化计时器且无法更改时定义的。与System.Timers.Timer类类似,该类旨在用作多线程环境中的基于服务器或服务的组件。它没有用户界面,并且在运行时不可见。
- System.Windows.Forms.Timer (仅.NET Framework):一个Windows Forms组件,该组件定期触发事件。该组件没有用户界面,并且设计用于单线程环境。
- System.Web.UI.Timer (仅.NET Framework):一个ASP.NET组件,该组件定期执行异步或同步网页回发。