Partilhar via


Uso de tempo limite

Use tempos limite para especificar o tempo máximo que um chamador está disposto a aguardar a conclusão de uma chamada de método.

Um tempo limite pode levar a forma de um parâmetro para a chamada do método da seguinte maneira.

server.PerformOperation(timeout)
server.PerformOperation(timeout);

Como alternativa, um tempo limite pode ser usado como a seguir como uma propriedade na classe de servidor.

server.Timeout = timeout
server.PerformOperation()
server.Timeout = timeout;
server.PerformOperation();   

Você deve favorecer a primeira abordagem, pois a associação entre a operação e o tempo limite é mais clara. A abordagem baseada na propriedade talvez seja melhor se a classe de servidor é projetada para ser um componente usado com designers visuais.

Historicamente, os tempos limite ter foi representado por números inteiros. Tempos limite de número inteiro pode ser difícil de usar porque não está óbvio qual é a unidade do tempo limite e é difícil traduzir a unidades de tempo para o milissegundo comumente usado.

Uma abordagem melhor é usar o TimeSpan estrutura como o tipo de tempo limite. TimeSpansoluciona os problemas com os tempos limite de número inteiro mencionados acima. O exemplo de código a seguir mostra como usar o tempo limite do tipo TimeSpan .

Public Class Server
   Public Sub PerformOperation(timeout As TimeSpan)
      ' Insert code for the method here.
      Console.WriteLine("performing operation with timeout {0}", _
        timeout.ToString())
   End Sub
End Class

public class Server
{
   public void PerformOperation(TimeSpan timeout)
   {
      // Insert code for the method here.
      Console.WriteLine("performing operation with timeout {0}", 
        timeout.ToString());
   }
}
public ref class Server
{
public:
    void PerformOperation(TimeSpan timeout)
    {
        // Insert code for the method here.
        Console::WriteLine("performing operation with timeout {0}",
            timeout.ToString());
    }
};

Se o tempo limite é definido como TimeSpan(0), o método deve acionar uma exceção se a operação não foi concluída imediatamente. Se o tempo limite é TimeSpan.MaxValue, a operação deve aguardar indefinidamente sem tempo limite, como se houvesse nenhum tempo limite definido. Uma classe de servidor não é necessário para dar suporte a qualquer um desses valores, mas ele deve lançar uma ArgumentException se um valor sem suporte de tempo limite é especificado.

Se um tempo limite expirar e uma exceção é lançada, a classe de servidor deve cancelar a operação subjacente.

Se o tempo limite padrão é usado, a classe de servidor deve incluir uma propriedade estática, especificando o tempo limite para ser usado se o usuário não especificar uma. O exemplo de código a seguir demonstra como implementar uma propriedade que especifica o tempo limite padrão.

Class ServerWithDefault
   Private Shared defaultTimeout As New TimeSpan(1000)

   Public Overloads Sub PerformOperation()
      Me.PerformOperation(DefaultOperationTimeout)
   End Sub 

   Public Overloads Sub PerformOperation(timeout As TimeSpan)
      ' Insert code here.
      Console.WriteLine("performing operation with timeout {0}", _
        timeout.ToString())
   End Sub 

   Public Shared ReadOnly Property DefaultOperationTimeout As TimeSpan
      Get
         Return defaultTimeout
      End Get
   End Property
End Class 

class ServerWithDefault
{
   static TimeSpan defaultTimeout = new TimeSpan(1000); 

   public void PerformOperation()
   {
      this.PerformOperation(DefaultOperationTimeout);
   }

   public void PerformOperation(TimeSpan timeout)
   {
      // Insert code here.
      Console.WriteLine("performing operation with timeout {0}", 
        timeout.ToString());
   }

   public static TimeSpan DefaultOperationTimeout
   {
      get
      {
         return defaultTimeout;
      }
   }
}
ref class ServerWithDefault
{
private:
    static TimeSpan defaultTimeout = TimeSpan(1000);

public:
    void PerformOperation()
    {
        this->PerformOperation(DefaultOperationTimeout);
    }

    void PerformOperation(TimeSpan timeout)
    {
        // Insert code here.
        Console::WriteLine("performing operation with timeout {0}",
            timeout.ToString());
    }

    static property TimeSpan DefaultOperationTimeout
    {
       TimeSpan get()
       {
           return defaultTimeout;
       }
    }
};

Tipos de não conseguir resolver os tempos limite para a resolução de um TimeSpan deve arredondar o tempo limite para o intervalo mais próximo que pode ser acomodado. Por exemplo, um tipo que pode esperar apenas em incrementos de um segundo deve arredondar para o segundo mais próximo. Uma exceção a essa regra é quando um valor é arredondado para baixo para zero. Nesse caso, o tempo limite deve ser arredondado para cima os possíveis mínimo de tempo limite. Arredondamento afastando de zero impede loops de espera ocupado, onde o valor de tempo limite zero faz com que 100% de utilização de processador.

Além disso, é recomendável que você lançar uma exceção quando um tempo limite expira em vez de retornar um código de erro. Expiração de um tempo limite significa que a operação não foi concluída com êxito e, portanto, deve ser tratada e manipulada como qualquer outro erro de tempo de execução. Para obter mais informações, consulte Diretrizes de design para exceções.

No caso de uma operação assíncrona com um tempo limite, a função de retorno de chamada deve ser chamada e acessado de uma exceção lançada quando os resultados da operação são primeiro. This is illustrated in the following code example.

Sub OnReceiveCompleted(ByVal sender As System.Object, ByVal asyncResult As ReceiveCompletedEventArgs)
   Dim queue As MessageQueue = CType(sender, MessageQueue)
   ' The following code will throw an exception
   ' if BeginReceive has timed out.
   Dim message As Message = queue.EndReceive(asyncResult.AsyncResult)
   Console.WriteLine(("Message: " + CStr(message.Body)))
   queue.BeginReceive(New TimeSpan(1, 0, 0))
End Sub 
void OnReceiveCompleted(Object sender, ReceiveCompletedEventArgs asyncResult)
{
   MessageQueue queue = (MessageQueue) sender;
   // The following code will throw an exception
   // if BeginReceive has timed out.
   Message message = queue.EndReceive(asyncResult.AsyncResult);
   Console.WriteLine("Message: " + (string)message.Body);
queue.BeginReceive(new TimeSpan(1,0,0));
}

Portions Copyright 2005 Microsoft Corporation. Todos os direitos reservados.

Portions Copyright Addison-Wesley Corporation. Todos os direitos reservados.

Para obter mais informações sobre as diretrizes de design, consulte a "diretrizes de Design do Framework: Convenções, idiomas e padrões de reutilizável.Bibliotecas de rede" catálogo por Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.

Consulte também

Conceitos

Diretrizes de uso

Outros recursos

Diretrizes de Design para desenvolvimento bibliotecas de classe

Padrões de Design de programação assíncrona