繁体   English   中英

async / await 不等待任务完成

[英]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;
    }
}

更多信息:

  1. .net-core 3.1 用于表单和 Web 服务。
  2. 客户端通过 grpc.net.client 连接到服务

谢谢

编辑

我知道通信有效,因为如果我执行诸如 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM