提问人:VivekDev 提问时间:8/4/2023 最后编辑:Guru StronVivekDev 更新时间:8/4/2023 访问量:100
Console.Error.WriteLineAsync() vs Console.WriteLine,有何不同。为什么后面会抛出异常?
Console.Error.WriteLineAsync() vs Console.WriteLine, what is the difference. Why does the later throw exception?
问:
我正在尝试了解 StreamJsonRpc 并从这里运行一个示例。
我在这里创建了一个调低的示例。它包含服务器和客户端,并通过 StreamJsonRpc 进行通信。
在服务器中,当我使用 Console.WriteLine 时,它会抛出异常。当我恢复使用 await Console.Error.WriteLineAsync() 时,它运行良好。
为什么?看起来与我缺少的 await 异步有关。
以下方法有效。
private static async Task RespondToRpcRequestsUsingConsoleErrorAsync(Stream stream, int clientId)
{
await Console.Error.WriteLineAsync($"Connection request #{clientId} received. Spinning off an async Task to cater to requests.");
var jsonRpc = JsonRpc.Attach(stream, new Server());
await Console.Error.WriteLineAsync($"JSON-RPC listener attached to #{clientId}. Waiting for requests...");
await jsonRpc.Completion;
await Console.Error.WriteLineAsync($"Connection #{clientId} terminated.");
}
以下引发异常。您可以在下面的 Console.WriteLine() 中看到替换了上面的 await Console.Error.WriteLineAsync()。
private static async Task RespondToRpcRequestsUsingConsoleAsync(Stream stream, int clientId)
{
Console.WriteLine($"Connection request #{clientId} received. Spinning off an async Task to cater to requests.");
var jsonRpc = JsonRpc.Attach(stream, new Server());
Console.WriteLine($"JSON-RPC listener attached to #{clientId}. Waiting for requests...");
await jsonRpc.Completion;
Console.WriteLine($"Connection #{clientId} terminated.");
}
我尝试使用jsonRpc.Completion.Wait()和jsonRpc.Completion.GetAwaiter()。GetResult();如下所示,但没有成功。
private static void RespondToRpcRequestsUsingConsoleWithWait(Stream stream, int clientId)
{
Console.WriteLine($"Connection request #{clientId} received. Spinning off an async Task to cater to requests.");
var jsonRpc = JsonRpc.Attach(stream, new Server());
Console.WriteLine($"JSON-RPC listener attached to #{clientId}. Waiting for requests...");
jsonRpc.Completion.Wait(); // SEE HERE
Console.WriteLine($"Connection #{clientId} terminated.");
}
private static void RespondToRpcRequestsUsingConsoleWithAwaiterAndResult(Stream stream, int clientId)
{
Console.WriteLine($"Connection request #{clientId} received. Spinning off an async Task to cater to requests.");
var jsonRpc = JsonRpc.Attach(stream, new Server());
Console.WriteLine($"JSON-RPC listener attached to #{clientId}. Waiting for requests...");
jsonRpc.Completion.GetAwaiter().GetResult(); // SEE HERE
Console.WriteLine($"Connection #{clientId} terminated.");
}
如何运行该示例。
- 只需在 Visual Studio 中打开它,将客户端设置为启动项目,然后按 F5 即可。
- 使用命令行,cd 进入客户端项目并运行它。
cd JsonRpcStdIoClient
dotnet run --project ./JsonRpcStdIoClient.csproj
答:
3赞
Guru Stron
8/4/2023
#1
这与.您正在使用 / 在进程之间进行通信,请写入 。因此,当您在服务器上调用它时,至少从角度来看,它会向通信通道发送一些随机数据,而这些数据似乎无法处理,因此结果。 另一方面,写入标准错误流,因此不会影响通信通道。async
StandardInput
StandardOutput
Console.WriteLine
StandardOutput
JsonRpc
JsonRpc
Console.Error
作为实验,删除服务器中的所有内容,并为客户端添加对双工流的监视:Console.WriteLine
// setup process and stdioStream
var monitoringStream = new MonitoringStream(stdioStream);
var inwr = new MemoryStream();
var outwr = new MemoryStream();
monitoringStream.DidRead += (s, e) => inwr.Write(e);
monitoringStream.DidWrite += (s, e) => outwr.Write(e);
try
{
await ActAsRpcClientAsync(monitoringStream);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("----\nIn:\n");
Console.WriteLine(Encoding.UTF8.GetString(inwr.ToArray()));
Console.WriteLine("----\nOut:\n");
Console.WriteLine(Encoding.UTF8.GetString(outwr.ToArray()));
这导致类似的东西
Connected. Sending request...
Received request: 3 + 5
3 + 5 = 8
----
In:
Content-Length: 35
{"jsonrpc":"2.0","id":2,"result":8}
----
Out:
Content-Length: 54
{"jsonrpc":"2.0","id":2,"method":"Add","params":[3,5]}
评论