繁体   English   中英

C#中的计时器在单独的线程中运行并更改一些变量

[英]Timer in C# running in a separate thread and changing some variables

我正在用C#编写一个应用程序,该应用程序每1秒从连接到串行端口的设备读取一些值。 为此,我想让一个计时器在单独的线程中运行,该计时器从“串行端口”中读取值,并在不同的标签中显示这些值,然后将它们绘制在图表中,然后将它们存储在集合中,因为我之后需要计算一些统计信息。 。

我设法做到了,但是使用了公共收藏集,我不喜欢...

我面临的问题是每次调用计时器时如何在不使用公共变量的情况下更改集合变量...

谢谢你的帮助...!

这是代码的一部分:

private void btnStart_Click(object sender, EventArgs e)
{
    timer1.Interval = 1000;
    timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
    Thread task = new Thread(ReadValues);
    task.Start();
}

public void ReadValues() 
{    
    try
    {  
        temp.Add(TemperatureController.readTemperatureinKelvinInputA());
        time.Add(DateTime.Now);              
    }
    catch (Exception)
    {               
    }

    string stringTime = String.Format("{0:HH:mm:ss}", DateTime.Now);

    DispTemperature(temp.Last());

    PlotAppendTemp(stringTime, temp.Last());    

    Thread.Sleep(0);
}

其中集合变量“ temp”和“ time”是之前定义的公共变量。 TemperatureController.readTemperatureinKelvinInputA()是库中的一个函数,可从串行端口读取温度并返回双精度值。 DispTemperature()和PlotAppendTemp()函数使用安全线程以表格形式显示值。

我希望“时间”和“临时”集合是私有变量,而不是公共变量。

将变量用作公共变量不是一个好主意,这就是为什么您始终不喜欢它的原因。 我想您已经publictimetemp集合,因为它们也被另一部分代码使用。 如果不在特定类之外的任何地方使用它们,那么您可以按照Iridium的建议将它们private

如果这些集合在系统的其他部分中使用,则建议您标识使用特定集合的系统的所有部分。 然后,您必须将这些交互减少到最低限度,从而导致代码的整体重组。

如果未识别使用这些集合的代码部分,没有人能给出令人满意的答案。

希望我能帮上忙!

您不应该在每个计时器标记上产生一个新线程。 无论如何,最好还是删除计时器,并使用在每个周期后都休眠一会的Thread或BackgroundWorker。 在线程的一个周期内,从串行端口读取数据,然后使用lock()模式将它们添加到您的集合中。 在访问同一集合的其他任何地方使用lock()。

我建议使用字典,而键是DateTime,值是来自串行端口的数据。 比使用两个集合更好。

为什么不包装您的集合(就像其他人说的那样,一个通用的Dictionary会比较理想)将您的数据保存在一个不错的类中,该类提供了以线程安全的方式向集合中添加(日期时间,温度)对的公共方法(就像其他人一样)说,使用lock()语句)。

然后在第二个线程中运行您的计时器,这是一个简单的循环。 因此它从串行端口读取数据,将数据添加到集合中(通过那些公共的线程安全方法),然后在重复之前休眠1秒钟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM