[英]async / await does not wait for task to finish
我正在尝试使用 gRPC 设置双向流。 我遵循了他们的教程,并阅读了 Stack Overflow 上的其他解决方案,但这些似乎都不能解决我的问题。
出于测试目的,我创建了一个简单的按钮单击事件,旨在将这一切都关闭,如下所示。 当我等待所有调用时, message
在 await resultTask
完成之前被处理。 据我了解,在完成作用域之前, await
运算符应该一直await
直到resultTask
完成。
有人可以帮助概述我在这里做错了什么吗?
private async void B_Click(object sender, EventArgs e)
{
try
{
await CallServer();
}
catch (Exception exception)
{
_box.Text = exception.Message;
}
}
private static async Task CallServer()
{
Greeter.GreeterClient client = new Greeter.GreeterClient(GrpcChannel.ForAddress("https://localhost:5001"));
using var message = client.Echos();
var resultTask = Task.Run(action: (async () =>
{
while (await message.ResponseStream.MoveNext(CancellationToken.None))
{
//Write out the result of the response
}
}));
List<HelloRequest> hellos = new List<HelloRequest>();
for (int i = 0; i < 10; i++)
{
hellos.Add(new HelloRequest() { Name = i.ToString() });
}
foreach (var hello in hellos)
{
await message.RequestStream.WriteAsync(hello);
}
await message.RequestStream.CompleteAsync();
await resultTask;
}
}
更多信息:
谢谢
编辑
我知道通信有效,因为如果我执行诸如 Console.ReadKey() 之类的操作,或者我using var message = client.Echos()
替换为var message = client.Echos()
消息返回正常(但它仍然没有等待)。
也就是说,这是原型:
语法 = "proto3"; option csharp_namespace = "GrpcService1";
包问候;
service Greeter { rpc Echos (stream HelloRequest) 返回 (stream .greet.HelloReply); }
消息 HelloRequest { 字符串名称 = 1; }
消息 HelloReply { 字符串消息 = 1; }
和服务器代码:
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override async Task Echos(IAsyncStreamReader<HelloRequest> requestStream, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
while (await requestStream.MoveNext())
{
await responseStream.WriteAsync(new HelloReply() {Message = "Hello " + requestStream.Current.Name});
}
}
}
}
感谢您的反馈,我通过重构未完成等待的方法设法解决了该问题。 我删除了Task.Run
并将其替换为返回值的async
方法:
private async Task CallServer()
{
Greeter.GreeterClient client = new Greeter.GreeterClient(GrpcChannel.ForAddress("https://localhost:5001"));
using var message = client.Echos();
var resultTask = CompletedTask(message);
List<HelloRequest> hellos = new List<HelloRequest>();
for (int i = 0; i < 10; i++)
{
hellos.Add(new HelloRequest() { Name = i.ToString() });
}
foreach (var hello in hellos)
{
await message.RequestStream.WriteAsync(hello);
}
await message.RequestStream.CompleteAsync();
var x = await resultTask;
_box.Text += "Done!";
}
private async Task<bool> CompletedTask(AsyncDuplexStreamingCall<HelloRequest, HelloReply> message)
{
await foreach (var result in message.ResponseStream.ReadAllAsync())
{
_box.Text += result.Message + @"\r\n";
}
return true;
}
Task.Run
正在返回一个返回类型为void
的方法签名,这就是它不等待答案的原因。 将其更改为引用具有返回类型的方法解决了该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.