如何在 C# 中的异步方法中同步执行方法?

How to execute a method synchronously inside of an async method in 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");
    }

如评论中所述,您在这里关注的不仅仅是同步/异步,还涉及并发资源访问。

当您使用任务时,它们由您无法直接控制的线程池的不同线程处理。

正如您在问题评论中再次建议的那样,您可以使用互斥锁以受控方式包装所有打印语句。

1) 任务的线程获取互斥量(或等待)

2)任务线程打印所有语句

3)任务线程释放互斥量

确保主线程在开始任务之前创建互斥体并在任务开始之前释放它。在构造函数中,您可以指定是否希望当前线程拥有互斥锁(在您的情况下为 false)。

使用 lock,序列化执行您的 print 代码

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

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");
    }
}