Windows 窗体 CPU 使用率高

问题描述 投票:0回答:1

对于 C# 来说相对较新。我制作了一个 Windows 窗体来监视文件中的更改。该程序占用了我 30% 的 CPU,我想让它运行得轻一点。运行诊断会话后,我可以看到 Run() 使用了几乎一半的程序资源。有什么办法可以优化这个吗?

static void Run()
{
    using (FileSystemWatcher watcher = new FileSystemWatcher())
    {
        watcher.Path = Path.GetDirectoryName(path);
        watcher.Filter = Path.GetFileName(path);

        watcher.Changed += OnChanged;
        watcher.Renamed += OnRenamed;

        watcher.EnableRaisingEvents = true;

        Debug.WriteLine("Running Reader");
        while (!cts.Token.IsCancellationRequested) ;
    }
}

这是我的CPU使用情况。

CPU usage

我的关闭线程的脚本也相当繁重,使用了近 30%

static CancellationTokenSource cts = new CancellationTokenSource();

private async void buttonRun_Click(object sender, EventArgs e)
{
    buttonRun.Enabled = false; // Disable the button to prevent multiple clicks

    listBoxStatus.Items.Add($"Line Reader Started! \t Time: {DateTime.Now}");
    listBoxStatus.Items.Add("");

    status = "Running";
    statusApplier();

    try
    {
        await Task.Run(() =>
        {
            LogApplicationStart();
            LoadComparisonFileLines();
            Run();
        }, cts.Token);
    }
    catch (OperationCanceledException)
    {
        listBoxStatus.Items.Add($"Task was cancelled! \t Time: {DateTime.Now}");
    }
    catch (Exception ex) // Catch any other exceptions
    {
        listBoxStatus.Items.Add($"An error occurred: {ex.Message}");
    }
    finally
    {
        cts.Dispose(); // Dispose the CancellationTokenSource
        cts = new CancellationTokenSource(); // Reset the token source
        buttonRun.Enabled = true; // Enable the button after the task is completed or if an error occurs

        if (listBoxStatus.Items.Count > 0 && listBoxStatus.Items[listBoxStatus.Items.Count - 1].ToString().Contains("Change"))
        {
            listBoxStatus.Items.Add("");
        }

        listBoxStatus.Items.Add($"Line Reader Ended! \t Time: {DateTime.Now}");
        listBoxStatus.Items.Add("");

        status = "Stopped";
        statusApplier();

        LogApplicationEnd();
    }
}

private void buttonStop_Click(object sender, EventArgs e)
{
    cts.Cancel(); // Cancel the task
}

我非常感谢任何帮助。 谢谢

我不知道如何比我已经使用的 FileSystemWatcher 更有效地使用它

c# .net winforms filesystemwatcher
1个回答
0
投票

造成CPU占用率高的罪魁祸首就是while循环,而事实上,程序中不应该存在这种几乎无穷无尽的空循环。

代码最简单的解决方案是将此循环替换为

cts.WaitHandle.WaitOne();

但是您的代码还有另一个问题。您的逻辑是使用一个按钮开始观看,使用另一个按钮停止观看,因此您应该将

finally
部分和处理
FileSystemWatcher
的部分放在停止按钮的回调中。这个
CancellationTokenSource
是多余的。

© www.soinside.com 2019 - 2024. All rights reserved.