我正在使用 dnp3 nuget 包,我想在 WPF 中实现它,我通过参考此示例来实现它https://github.com/stepfunc/dnp3/blob/master/ffi/bindings/dotnet /examples/master/Program.cs 我设法通过 MVVM 方法实现它,它动态显示它收到的消息(在 gif 中它显示一个错误,因为它没有创建另一个将连接的程序,但重要的是它正在更新)。
但我创建了另一个更简单的项目来在 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
}
}
正如之前评论的(回答“性能问题”):
while
循环正在运行,没有任何暂停或工作。您需要用一些工作或简单的暂停来填充循环(Thread.Sleep(10)
/await Task.Delay(10)
)。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());
}
}
伊万, 如果您还在,请问您在构建程序时是否遇到过 DNP3CLRAdapter 的任何问题? 我在部署项目时不断遇到异常。