diff --git a/aspnetcore/grpc/client.md b/aspnetcore/grpc/client.md index c167af01b3..389b63d32d 100644 --- a/aspnetcore/grpc/client.md +++ b/aspnetcore/grpc/client.md @@ -25,9 +25,7 @@ var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greet.GreeterClient(channel); ``` -A channel represents a long-lived connection to a gRPC service. When a channel is created it is configured with options related to calling a service. For example, the `HttpClient` used to make calls, the maximum send and receive message size, and logging can be specified on `GrpcChannelOptions` and used with `GrpcChannel.ForAddress`. For a complete list of options, see [client configuration options](xref:grpc/configuration#configure-client-options). - -Creating a channel can be an expensive operation and reusing a channel for gRPC calls offers performance benefits. Multiple concrete gRPC clients can be created from a channel, including different types of clients. Concrete gRPC client types are lightweight objects and can be created when needed. +A channel represents a long-lived connection to a gRPC service. When a channel is created, it is configured with options related to calling a service. For example, the `HttpClient` used to make calls, the maximum send and receive message size, and logging can be specified on `GrpcChannelOptions` and used with `GrpcChannel.ForAddress`. For a complete list of options, see [client configuration options](xref:grpc/configuration#configure-client-options). ```csharp var channel = GrpcChannel.ForAddress("https://localhost:5001"); @@ -38,7 +36,15 @@ var counterClient = new Count.CounterClient(channel); // Use clients to call gRPC services ``` -`GrpcChannel.ForAddress` isn't the only option for creating a gRPC client. If you are calling gRPC services from an ASP.NET Core app, consider [gRPC client factory integration](xref:grpc/clientfactory). gRPC integration with `HttpClientFactory` offers a centralized alternative to creating gRPC clients. +Channel and client performance and usage: + +* Creating a channel can be an expensive operation. Reusing a channel for gRPC calls provides performance benefits. +* gRPC clients are created with channels. gRPC clients are lightweight objects and don't need to be cached or reused. +* Multiple gRPC clients can be created from a channel, including different types of clients. +* A channel and clients created from the channel can safely be used by multiple threads. +* Clients created from the channel can make multiple simultaneous calls. + +`GrpcChannel.ForAddress` isn't the only option for creating a gRPC client. If you're calling gRPC services from an ASP.NET Core app, consider [gRPC client factory integration](xref:grpc/clientfactory). gRPC integration with `HttpClientFactory` offers a centralized alternative to creating gRPC clients. > [!NOTE] > Additional configuration is required to [call insecure gRPC services with the .NET client](xref:grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client). @@ -87,7 +93,7 @@ using (var call = client.SayHellos(new HelloRequest { Name = "World" })) } ``` -If you are using C# 8 or later then the `await foreach` syntax can be used to read messages. The `IAsyncStreamReader.ReadAllAsync()` extension method reads all messages from the response stream: +If you are using C# 8 or later, the `await foreach` syntax can be used to read messages. The `IAsyncStreamReader.ReadAllAsync()` extension method reads all messages from the response stream: ```csharp var client = new Greet.GreeterClient(channel); @@ -103,7 +109,7 @@ using (var call = client.SayHellos(new HelloRequest { Name = "World" })) ### Client streaming call -A client streaming call starts *without* the client sending a message. The client can choose to send sends messages with `RequestStream.WriteAsync`. When the client has finished sending messages `RequestStream.CompleteAsync` should be called to notify the service. The call is finished when the service returns a response message. +A client streaming call starts *without* the client sending a message. The client can choose to send messages with `RequestStream.WriteAsync`. When the client has finished sending messages `RequestStream.CompleteAsync` should be called to notify the service. The call is finished when the service returns a response message. ```csharp var client = new Counter.CounterClient(channel);