C# 保证异步方法顺序执行

通常会有一些异步方法需要顺序执行,如对一个Socket进行异步发送,想要确保信息按照调用异步时的顺序进行发送,但使用普通的异步方法不能保证发送顺序,会导致对方接受结果为乱序发送。

具体实现思路:首先为每一个顺序声明一个ValueTask或Task全局变量a,然后每次调用异步方法时等待a中存储的前一个ValueTask或Task,同时将此次异步方法返回给a,这样就能实现异步的顺序发送。具体代码如下:

接收端代码:

{
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Bind(IPEndPoint.Parse("127.0.0.1:8888"));
    byte[] buffer = new byte[10240];
    socket.Listen(1);
    Socket client = socket.Accept();
    Thread.Sleep(5000);
    client.Receive(buffer);
    Console.WriteLine(Encoding.UTF8.GetString(buffer));
}

发送端代码(不进行异步顺序处理):

{
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect(IPEndPoint.Parse("127.0.0.1:8888"));
    {
    	for (int i = 0; i < 100; i++)
        {
        	Send_(socket, Encoding.UTF8.GetBytes($"{i}\n"));
        }
    }
}

static async void Send_(Socket socket,ReadOnlyMemory<byte>msgMem)
{
    await Task.Delay(random.Next(10, 50));    //模拟多个方法处理时间不同操作
    socket.SendAsync(msgMem);
}

普通异步方法输出:在这里插入图片描述

发送端代码(顺序异步):

{
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect(IPEndPoint.Parse("127.0.0.1:8888"));
    {
        for (int i = 0; i < 100; i++)
        {
            globalVT = SendNext(socket, Encoding.UTF8.GetBytes($"{i}\n"));
        }
    }
}
static ValueTask<int> globalVT = default;
static async ValueTask<int> SendNext(Socket socket, ReadOnlyMemory<byte> msgMem)
{
    //在一个代码块中,阻塞等待和赋值给globalVT二者不能同时发生,曲线救国
    await globalVT;
    return await send(socket, msgMem);
}
static async ValueTask<int> send(Socket socket, ReadOnlyMemory<byte> msgMem)
{
    //异步方法,模拟延时操作
    await Task.Delay(random.Next(10, 50));
    return await socket.SendAsync(msgMem);
}  

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值