【发布时间】:2012-10-11 10:47:44
【问题描述】:
我想让一个类每秒更改一个属性。更改应该发生在类级别而不是主线程中,我该怎么做?
【问题讨论】:
标签: c# multithreading events
我想让一个类每秒更改一个属性。更改应该发生在类级别而不是主线程中,我该怎么做?
【问题讨论】:
标签: c# multithreading events
你应该使用 System.Threading.Timer:
private System.Threading.Timer timer;
public YourClass()
{
timer = new System.Threading.Timer(UpdateProperty, null, 1000, 1000);
}
private void UpdateProperty(object state)
{
lock(this)
{
// Update property here.
}
}
请记住在读取属性时锁定实例,因为 UpdateProperty 是在不同的线程(线程池线程)中调用的
【讨论】:
如果你想在不同的线程上做,请使用BackgroundWorker并将更改属性的逻辑放在DoWork中。
如果你想重复做某事,你应该在后台工作人员DoWork() 方法中使用loop,而不是使用Timer 类,因为与BackgroundWorker 一起使用似乎毫无意义。这是一些粗略的代码:
public Form1()
{
InitializeComponent();
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(DoWork);
}
private void DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int delay = 1000; // 1 second
while (!worker.CancellationPending)
{
do something
Thread.Sleep(delay);
}
e.Cancel = true;
}
每当您想停止属性更新时,都会像这样在工作实例上调用CancelAsync -
worker.CancelAsync();
【讨论】:
现在在 .net 6 中非常简单。
using System;
using System. Threading;
using PeriodicTimer timer = new (TimeSpan.FromSeconds (1));|
while (await timer.WaitForNextTickAsync ())
{
//implement your code here
}
【讨论】:
在表单中,最简单的方法是创建一个计时器。
public Form1()
{
InitializeComponent();
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(Tick);
}
private void Tick(object sender, EventArgs e)
{ ... }
我的猜测是你甚至可以在表单之外使用 Timer,因为它是一个组件而不是一个控件。
【讨论】: