首页 > 解决方案 > 如何在 c# 中的异步方法内同步执行方法?

问题描述

我开始使用异步任务来创建客户端和服务器响应的模拟,我让它工作但现在我想更好地控制每个客户端发送的消息,我通过制作自定义 printLine 在控制台中打印来获得它颜色和标签,但是现在,因为服务器和客户端异步运行,控制台上的消息重叠:

[Server]>       Wating for a conection...
[Client #0]>    [Client #1]>    Socket connected to -> [SomeIP]:11111
Socket connected to -> [SomeIP]:11111
[Server]>       Text received -> Test Client<EOF>
[Client #1]>    Message from server -> Test Server
[Server]>       Wating for a conection...
[Server]>       Text received -> Test Client<EOF>
[Client #0]>    [Server]>       Message from server -> Test Server

这是因为我自己的 printLine 方法不是在一行代码中执行的,我该如何同步运行该方法以等待该方法执行完成?谢谢和对不起我的英语。

这是运行任务的方法:

    static async Task Start(){
        Server.Server server = new Server.Server();
        Client.Client client0 = new Client.Client(0);
        Client.Client client1 = new Client.Client(1);

        var serverTask = Task.Run(() => server.ExecuteServer());
        var clientTask0 = Task.Run(() => client0.ExecuteClient());
        var clientTask1 = Task.Run(() => client1.ExecuteClient());

        await clientTask1;
        await clientTask0;
        Console.WriteLine("Done");
    }

这是我自己的 PrintLine 方法

    void printLine(string line){
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("[Client #" + clientID + "]>\t");
        Console.ResetColor();
        Console.WriteLine(line + "\n");
    }

标签: c#async-awaitsynchronizationtask

解决方案


使用lock, 序列化打印代码的执行

lock 语句获取给定对象的互斥锁,执行语句块,然后释放锁。持有锁时,持有锁的线程可以再次获取和释放锁。任何其他线程都被阻止获取锁并等待直到锁被释放。

private readonly object _sync = new object();

void printLine(string line)
{
    lock (_sync)
    {
        Console.ForegroundColor = ConsoleColor.Cyan;
        Console.Write("[Client #" + clientID + "]>\t");
        Console.ResetColor();
        Console.WriteLine(line + "\n");
    }
}

推荐阅读