用C# 的System.Threading.Channels 模拟2台PLC, 用消息队列实现异步任务之间的通信

using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Channels;

Channel<Wrapper> channel = Channel.CreateUnbounded<Wrapper>();

Task.Run(async () =>
{
    await Task.WhenAll(Sender1(channel), Sender2(channel));
});

JsonSerializerOptions options = new()
{
    WriteIndented = true,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

await foreach (var item in channel.Reader.ReadAllAsync())
{
    //string json = item.MessageType switch
    //{
    //    MessageType.MyMessage1 => JsonSerializer.Serialize((MyMessage1)item.Message, options),
    //    MessageType.MyMessage2 => JsonSerializer.Serialize((MyMessage2)item.Message, options),
    //    _ => throw new InvalidOperationException("Unknown message type")
    //};
    string json = JsonSerializer.Serialize(item, options);
    Console.WriteLine(json);
}

//PLC1 发消息
async Task Sender1(Channel<Wrapper> channel)
{
    int id = 0;
    while (true)
    {
        await Task.Delay(100);
        Random random = new();
        var a = random.Next(1, 1000);
        var message1 = new MyMessage1
        {
            Id = id++,
            Message = a,
            Client = "sender1",
            DateTime = DateTime.Now
        };
        await channel.Writer.WriteAsync(new Wrapper
        {
            MessageType = MessageType.MyMessage1,
            Message = message1
        });
    }
}

//PLC2 发消息
async Task Sender2(Channel<Wrapper> channel)
{
    int id = 0;
    while (true)
    {
        await Task.Delay(100);
        Random random = new();
        var a = random.Next(-1000, 0);
        var message2 = new MyMessage2
        {
            Id = id++,
            Message = a,
            Client = "sender2",
            DateTime = DateTime.Now
        };
        await channel.Writer.WriteAsync(new Wrapper
        {
            MessageType = MessageType.MyMessage2,
            Message = message2
        });
    }
}

[Flags]
public enum MessageType
{
    MyMessage1,
    MyMessage2
}

public class Wrapper
{
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public MessageType MessageType { get; set; }
    public BaseMessage Message { get; set; }
}

public abstract class BaseMessage
{
    public int Id { get; set; }
    public string? Client { get; set; }
    public DateTime DateTime { get; set; }
}

public class MyMessage1 : BaseMessage
{
    public float Message { get; set; }
}

public class MyMessage2 : BaseMessage
{
    public float Message { get; set; }
}

在这里插入图片描述
在真实的Plc中 , 可以用一个globalData注入到Ioc, 用 globalDada接收 最终reader的结果, 用messageType判断类型, 最终在globalData中写事件触发.

可以用2种数据类型替代Message, 例如class Message1 与 class Message2, 当messageType=1时, Message1有效, globalData接收Message1; 当messageType=2时, Message2有效, globalData接收Message2

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值