我的标签怎么不更新其内容? WPF .NET C#

时间:2016-08-26 08:59:14

标签: c# .net wpf timer

我目前正在乱搞计时器和标签以及性能计数器,因为我正在尝试使标签更新其内容到目前的CPU使用率(并以一定的间隔保持更新)

但由于某种原因,它只显示我的CPU使用率为0%且未更新。

是什么导致了这个错误。

$scope.items

XAML

[
  {
    "kode_produk": "PR_1"
  },
  {
    "kode_produk": "PR_2"
  },
  {
    "kode_produk": "PR_3"
  }
]

2 个答案:

答案 0 :(得分:2)

根据https://blogs.msdn.microsoft.com/bclteam/2006/06/02/how-to-read-performance-counters-ryan-byington/以及此SO帖子中的评论,您使用的方法可能需要再次拨打NextValue()并在两次通话之间暂停以使其生效。{ {3}}

所以,你要修改你的getCPUInfo()方法,看起来像这样:

public void getCPUInfo()
{

    PerformanceCounter cpuCounter;
    cpuCounter = new PerformanceCounter();
    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor Time";
    cpuCounter.InstanceName = "_Total";
    // Get Current Cpu Usage
    cpuCounter.NextValue();
    // Sleep
    Thread.Sleep(1000);
    // Get Current Cpu Usage again
    string currentCpuUsage = cpuCounter.NextValue() + "%";
    //Print it to the current label
    CPUUsage.Content = currentCpuUsage;
}

显然,我希望您明白在以UI为中心的程序中使用Thread.Sleep()是一件坏事,所以如果您采用这种方法,我会使用任务和延迟(我只是不这样做)知道你对TPL的熟悉程度,所以我不想引起任何进一步的混淆。)

以下是它的演示:

How to get the CPU Usage in C#?

话虽如此,你可以通过简单地做这样的事情来解决所有问题:

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;

namespace TestApp
{
    public partial class MainWindow : Window
    {
        PerformanceCounter cpuCounter;
        DispatcherTimer dtClockTime;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeCpuPerformanceCounter();
            InitializeDispatcherTimer();
        }

        void InitializeDispatcherTimer()
        {
            dtClockTime = new DispatcherTimer();
            dtClockTime.Interval = new TimeSpan(0, 0, 1); //in Hour, Minutes, Second.
            dtClockTime.Tick += dtClockTime_Tick;
            dtClockTime.IsEnabled = true;
            dtClockTime.Start();
        }

        void InitializeCpuPerformanceCounter()
        {
            cpuCounter = new PerformanceCounter();
            cpuCounter.CategoryName = "Processor";
            cpuCounter.CounterName = "% Processor Time";
            cpuCounter.InstanceName = "_Total";
        }

        private void dtClockTime_Tick(object sender, EventArgs e)
        {
            getCPUInfo();
        }

        public void getCPUInfo()
        {
            CPUUsage.Content = cpuCounter.NextValue() + "%";
        }
    }
}

这是一个演示:

enter image description here

它的工作原因是我没有在每个滴答声中实例化一个新的性能计数器,并且因为定时器有一秒间隔,这导致每个NextValue()呼叫之间所需的延迟。我将PerformanceCounterDispatcherTimer都存储为字段,只初始化一次。所以,这是一个更好的方法。

顺便说一句,两个测试的XAML代码非常简单:

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="525">
    <Grid>
        <Label x:Name="CPUUsage" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

修改

根据您在评论中的请求,如果您要使用原始方法,可以使用asyncawait。这样可以防止用户界面每隔一秒冻结一秒钟,就像使用Thread.Sleep()版本一样:

public async Task getCPUInfo()
{
    PerformanceCounter cpuCounter;
    cpuCounter = new PerformanceCounter();
    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor Time";
    cpuCounter.InstanceName = "_Total";
    // Get Current Cpu Usage
    cpuCounter.NextValue();
    // Delay
    await Task.Delay(1000);
    // Get Current Cpu Usage again
    string currentCpuUsage = cpuCounter.NextValue() + "%";
    //Print it to the current label
    CPUUsage.Content = currentCpuUsage;
}

您可以在MSDN上找到有关TPL的更多信息:

enter image description here

另外,我不能推荐Stephen Cleary的博客。这是一颗宝石。这是关于asyncawait的文章:

https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx

他还有很多其他文章,他的书也很优秀(不过,如果你负担不起,那本书中的所有内容都贯穿于他的博客中 - 他是一个好人)。

答案 1 :(得分:0)

使用以下代码

替换getCPUInfo()方法中的代码
    /// <summary>
    /// 
    /// </summary>
    public void getCPUInfo()
    {
        PerformanceCounter cpuCounter;
        cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";
        // Get Current Cpu Usage

        cpuCounter.NextValue(); // Added
        System.Threading.Thread.Sleep(1000); // Added
        // now matches task manager reading 
        float secondValue = cpuCounter.NextValue(); // Added

        string currentCpuUsage = secondValue + "%";
        //Print it to the current label
        CPUUsage.Content = currentCpuUsage;
    }

希望你的问题得到解决。