Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Linux 下的 Console.Read 将导致管道无法读取到消息 #139

Open
@lindexi

Description

@lindexi

在 Linux 下的 UOS 系统里面进行测试,如以下代码

varpeer=awaitipcProvider.GetAndConnectToPeerAsync(args[0]);peer.MessageReceived+=(sender,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");};awaitpeer.NotifyAsync(newIpcMessage("Hello",Encoding.UTF8.GetBytes($"Hello,进程号是{Environment.ProcessId} 发送过来消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");Console.Read();

那么以上的 MessageReceived 事件将不会被触发,且是因为底层的管道读取无法返回。一旦使用 Task.Run 包括起来,如以下代码,即可正常收到消息

Task.Run(async()=>{varpeer=awaitipcProvider.GetAndConnectToPeerAsync(args[0]);peer.MessageReceived+=(sender,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");};awaitpeer.NotifyAsync(newIpcMessage("Hello",Encoding.UTF8.GetBytes($"Hello,进程号是{Environment.ProcessId} 发送过来消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");});Console.Read();

如果给 Task.Run 加上 await 如以下代码,那将无法收到回复,依然是管道读取没有返回,可参考91043ee 的更改

awaitTask.Run(async()=>{varpeer=awaitipcProvider.GetAndConnectToPeerAsync(args[0]);peer.MessageReceived+=(sender,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");};awaitpeer.NotifyAsync(newIpcMessage("Hello",Encoding.UTF8.GetBytes($"Hello,进程号是{Environment.ProcessId} 发送过来消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");});Console.Read();

以上代码情况可以排除 Task Main 导致的问题,因为一旦将 Console.Read 换掉,那就可以正常读取到管道里面的消息,管道可以返回,如8d27486 代码更改

awaitTask.Run(async()=>{varpeer=awaitipcProvider.GetAndConnectToPeerAsync(args[0]);peer.MessageReceived+=(sender,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");};awaitpeer.NotifyAsync(newIpcMessage("Hello",Encoding.UTF8.GetBytes($"Hello,进程号是{Environment.ProcessId} 发送过来消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");});for(inti=0;i<int.MaxValue;i++){awaitTask.Delay(TimeSpan.FromSeconds(1));}

以上问题的简单复现代码:

internalclassProgram{privatestaticasyncTaskMain(string[]args){varipcProvider=newIpcProvider();ipcProvider.StartServer();if(args.Length==0){varcurrentName=ipcProvider.IpcContext.PipeName;// 将当前的进程的 Name 传递给另一个进程,用来达成通讯varmainModuleFileName=Process.GetCurrentProcess().MainModule.FileName;Console.WriteLine($"[{Environment.ProcessId}] 准备启动{mainModuleFileName} 参数:{currentName}");Process.Start(mainModuleFileName,currentName);}else{// 这是被启动的进程,主动连接发送消息Console.WriteLine($"[{Environment.ProcessId}] 开始连接对方进程");varpeer=awaitipcProvider.GetAndConnectToPeerAsync(args[0]);peer.MessageReceived+=(sender,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");};awaitpeer.NotifyAsync(newIpcMessage("Hello",Encoding.UTF8.GetBytes($"Hello,进程号是{Environment.ProcessId} 发送过来消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");}ipcProvider.PeerConnected+=(sender,connectedArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{connectedArgs.Peer.PeerName} 的连接");connectedArgs.Peer.MessageReceived+=async(o,messageArgs)=>{Console.WriteLine($"[{Environment.ProcessId}] 收到{messageArgs.PeerName} 的消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");awaitTask.Delay(TimeSpan.FromSeconds(1));// 反向发送消息给对方Console.WriteLine($"[{Environment.ProcessId}] 向{connectedArgs.Peer.PeerName} 回复消息");awaitconnectedArgs.Peer.NotifyAsync(newIpcMessage("回复",Encoding.UTF8.GetBytes($"收到你的消息")));Console.WriteLine($"[{Environment.ProcessId}] 完成向{connectedArgs.Peer.PeerName} 回复消息");};};Console.WriteLine($"[{Environment.ProcessId}] 等待退出");Console.Read();Console.WriteLine($"[{Environment.ProcessId}] 进程准备退出");}}

以上代码在 Windows 上正常,在 Linux 的 UOS 系统无法收到回复消息,也就是peer.MessageReceived 对应的事件没有触发,调试可以看到管道没有读取返回

详细的各个测试步骤请看#140

可能是 Linux 的 Console.Read 投毒

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp