Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O comportamento padrão de uma operação de serviço é o padrão de solicitação-resposta. Em um padrão de solicitação-resposta, o cliente aguarda a mensagem de resposta, mesmo que a operação de serviço seja representada no código como um void método. Com uma operação unidirecional, apenas uma mensagem é transmitida. O receptor não envia uma mensagem de resposta, nem o remetente espera uma.
Use o padrão de design unidirecional:
Quando o cliente deve chamar operações e não é afetado pelo resultado da operação no nível da operação.
Ao usar a classe NetMsmqBinding ou a classe MsmqIntegrationBinding. (Para obter mais informações sobre esse cenário, consulte Filas no WCF).
Quando uma operação é unidirecional, não há nenhuma mensagem de resposta para levar informações de erro de volta ao cliente. Você pode detectar condições de erro usando recursos da associação subjacente, como sessões confiáveis ou projetando um contrato de serviço duplex que usa duas operações unidirecionais — um contrato unidirecional do cliente para o serviço para chamar a operação de serviço e outro contrato unidirecional entre o serviço e o cliente para que o serviço possa enviar falhas de volta ao cliente usando um retorno de chamada que o cliente implementa.
Para criar um contrato de serviço unidirecional, defina seu contrato de serviço, aplique a OperationContractAttribute classe a cada operação e defina a IsOneWay propriedade como true, conforme mostrado no código de exemplo a seguir.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
[OperationContract(IsOneWay=true)]
void Add(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Subtract(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Multiply(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Divide(double n1, double n2);
}
Para obter um exemplo completo, consulte o exemplo unidirecional .
Bloqueio de clientes com operações unidirecionais
É importante perceber que, embora alguns aplicativos unidirecionais retornem assim que os dados de saída forem gravados na conexão de rede, em vários cenários, a implementação de uma associação ou de um serviço pode fazer com que um cliente WCF bloqueie o uso de operações unidirecionais. Em aplicativos cliente WCF, o objeto cliente WCF não retorna até que os dados de saída sejam gravados na conexão de rede. Isso é verdadeiro para todos os padrões de troca de mensagens, incluindo operações unidirecionais; isso significa que qualquer problema ao gravar os dados no transporte impede que o cliente retorne. Dependendo do problema, o resultado pode ser uma exceção ou um atraso no envio de mensagens para o serviço.
Por exemplo, se o transporte não puder encontrar o ponto de extremidade, uma exceção System.ServiceModel.EndpointNotFoundException será lançada sem muito atraso. No entanto, também é possível que o serviço não consiga ler os dados da transmissão por algum motivo, o que impede que a operação de envio de transporte do cliente retorne. Nesses casos, se o período Binding.SendTimeout na associação de transporte do cliente for excedido, um System.TimeoutException será gerado, mas não até que o período de tempo limite tenha sido excedido. Também é possível disparar tantas mensagens em um serviço que o serviço não pode processá-las após um determinado ponto. Nesse caso, também, o cliente unidirecional bloqueia até que o serviço possa processar as mensagens ou até que uma exceção seja gerada.
Outra variação é a situação em que a propriedade de serviço ServiceBehaviorAttribute.ConcurrencyMode é configurada para Single e a vinculação usa sessões. Nesse caso, o dispatcher impõe a ordenação nas mensagens de entrada (um requisito de sessões), o que impede que as mensagens subsequentes sejam lidas fora da rede até que o serviço tenha processado a mensagem anterior para essa sessão. Novamente, o cliente bloqueia, mas se uma exceção ocorre depende se o serviço é capaz de processar os dados de espera antes das configurações de tempo limite no cliente.
Você pode atenuar parte desse problema inserindo um buffer entre o objeto cliente e a operação de envio do transporte do cliente. Por exemplo, usar chamadas assíncronas ou usar uma fila de mensagens na memória pode permitir que o objeto cliente retorne rapidamente. Ambas as abordagens podem aumentar a funcionalidade, mas o tamanho do pool de threads e da fila de mensagens ainda impõem limites.
Em vez disso, é recomendável que você examine os vários controles no serviço, bem como no cliente, e teste os cenários do aplicativo para determinar a melhor configuração em ambos os lados. Por exemplo, se o uso de sessões estiver bloqueando o processamento de mensagens em seu serviço, você pode definir a propriedade ServiceBehaviorAttribute.InstanceContextMode para PerCall, permitindo que cada mensagem seja processada por uma instância de serviço diferente, e definir ConcurrencyMode para Multiple a fim de permitir que mais de um thread envie mensagens de cada vez. Outra abordagem é aumentar as cotas de leitura das associações de serviço e cliente.