WPF 的性能问题

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

我正在使用 dnp3 nuget 包,我想在 WPF 中实现它,我通过参考此示例来实现它https://github.com/stepfunc/dnp3/blob/master/ffi/bindings/dotnet /examples/master/Program.cs 我设法通过 MVVM 方法实现它,它动态显示它收到的消息(在 gif 中它显示一个错误,因为它没有创建另一个将连接的程序,但重要的是它正在更新)。

Example

但我创建了另一个更简单的项目来在 github 上进行演示,在我的项目中创建一个名为协议的类,并粘贴所有主示例,消除主函数并将私有函数更改为公共函数,然后在我的 MainWindow.xaml 中。 cs启动代码

    {
        public MainWindow()
        {
            InitializeComponent();
            // ANCHOR: logging_init
            // Initialize logging with the default configuration
            // This may only be called once during program initialization
            Logging.Configure(
                new LoggingConfig(),
                new Protocolo.ConsoleLogger()
            );
            // ANCHOR_END: logging_init

            // ANCHOR: runtime_init
            var runtime = new Runtime(new RuntimeConfig { NumCoreThreads = 4 });
            // ANCHOR_END: runtime_init

            // ANCHOR: create_master_channel
            var channel = MasterChannel.CreateTcpChannel(
                runtime,
                LinkErrorMode.Close,
               Protocolo. GetMasterChannelConfig(),
                new EndpointList("127.0.0.1:20000"),
                new ConnectStrategy(),
                new Protocolo.TestListener()
            );
            // ANCHOR_END: create_master_channel

                Task.Run(() => 
                {
                    try
                    {
                        Protocolo.RunChannel(channel).GetAwaiter().GetResult();
                    }
                    finally
                    {
                        // ANCHOR: runtime_shutdown
                        runtime.Shutdown();
                        // ANCHOR_END: runtime_shutdown
                    }
            }
            );

        }
    } 

我做了性能分析,RunChannel 是他们对 CPU 要求很高的东西

        public static async Task RunChannel(MasterChannel channel)
        {
            // ANCHOR: association_create
            var association = channel.AddAssociation(
                1024,
                GetAssociationConfig(),
                new TestReadHandler(),
                new TestAssocationHandler()
            );
            // ANCHOR_END: association_create

            // ANCHOR: add_poll
            var poll = channel.AddPoll(association, Request.ClassRequest(false, true, true, true), TimeSpan.FromSeconds(5));
            // ANCHOR_END: add_poll

            // start communications
            channel.Enable();

            while (true)
            {
              //Here there was a switch that read the commands that were entered into the console but it is unnecessary, with the empty while it continues to update

            }
        }

我不知道为什么,但如果没有,虽然收到的消息没有更新,(这些消息到达记录器)我必须保持这个功能始终处于活动状态,但我不知道如何在不消耗太多CPU的情况下做到这一点

要查看输出中的消息,您必须将

Console.WriteLine
更改为
Debug.WriteLine

   class ConsoleLogger : ILogger
    {
        public void OnMessage(LogLevel level, string message)
        {
            Console.Write($"{message}");
            //this is inside the master example in the github link
        }
    }
c# wpf performance user-interface dnp3
2个回答
2
投票

正如之前评论的(回答“性能问题”):

  1. 您的空
    while
    循环正在运行,没有任何暂停或工作。您需要用一些工作或简单的暂停来填充循环(
    Thread.Sleep(10)
    /
    await Task.Delay(10)
    )。
  2. 您的 RunChannel 方法没有任何
    await
    ,因此您应该收到 CS1998 警告“此异步方法缺少 'await'”,并且显然将其放入您的
    while
    循环中。

在DNP3 Github示例中,

await GetInputAsync()
循环内有
while
,它等待用户使用
Console.ReadLine()
输入并将输入的字符串返回到
switch
语句中。

所以:

public MainWindow()
{
    // InitializeComponent() and other stuff...

    Task.Run(async () => // Make it async
    {
        try
        {
            // You really didn't want GetAwaiter().GetResult().
            await Protocolo.RunChannel(channel);
        }
        finally
        {
            runtime.Shutdown();
        }
    });
}

public class Protocolo 
{
    public static async Task RunChannel(MasterChannel channel)
    {
        // Associations and polls stuff...

        while (true)
        {
            await Task.Delay(10); // Set some delay or...

            await SomeJob(); // ...or do some job or ...

            switch (await GetInputAsync())  // ...or take github's example
            {
                case "x":
                    return;                    
                default:
                    Console.WriteLine("Unknown command");
                    break;
            }
        }
    }

    public static Task SomeJob()
    {
        return Task.Run(() => 
        {
            for (int i = 0; i < 5; i++)
            {
                 Thread.Sleep(200); // 200 x 5 = Total task for 1 second
            }
        });
    }

    public static Task<string> GetInputAsync()
    {
        return Task.Run(() => Console.ReadLine());
    }       
}

0
投票

伊万, 如果您还在,请问您在构建程序时是否遇到过 DNP3CLRAdapter 的任何问题? 我在部署项目时不断遇到异常。

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