Использование времени ожидания
Используйте тайм-ауты для задания максимального времени, в течение которого вызывающий объект ожидает завершения вызова метода.
Тайм-аут может принимать форму параметра при вызове метода, как показано ниже.
server.PerformOperation(timeout)
server.PerformOperation(timeout);
С другой стороны, тайм-аут может использоваться как свойство в классе серверов.
server.Timeout = timeout
server.PerformOperation()
server.Timeout = timeout;
server.PerformOperation();
Предпочтительным является первый подход, поскольку в нем более понятна связь между операцией и тайм-аутом. Подход на основе свойства может оказаться лучше, если разработанный класс серверов должен представлять собой компонент, используемый с визуальным конструктором.
Исторически тайм-ауты представляются целыми числами. Тайм-аут, выраженный целыми числами, может оказаться неудобным, поскольку неясна его единица измерения и сложен ее перевод в общепринятые миллисекунды.
Лучше всего использовать в качестве типа таймаута структуру TimeSpan. TimeSpan устраняет проблемы с целыми таймаутами, о которых говорилось выше. В следующем примере кода показано, как использовать тайм-аут типа 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());
}
};
Если значение тайм-аута устанавливается в TimeSpan(0), то метод должен сгенерировать исключение, если операция не завершена немедленно. Если тайм-аут равен TimeSpan.MaxValue, эта операция должна ожидать неограниченно долго, как если бы тайм-аут не был задан. Для поддержки любого из этих значений серверный класс не требуется, но при задании неподдерживаемого значения тайм-аута должно быть сгенерировано исключение ArgumentException.
Если тайм-аут истек и сгенерировано исключение, серверный класс должен отменить основную операцию.
Если используется тайм-аут по умолчанию, серверный класс должен включать в себя статическое свойство, описывающее тайм-аут, которое будет использоваться, если тайм-аут не задается пользователем. В следующем примере кода демонстрируется реализация свойства, которое задает значение тайм-аута по умолчанию.
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;
}
}
};
Для типов, у которых отсутствует возможность округления с точностью TimeSpan, должно применяться округление тайм-аута до ближайшего подходящего интервала. Например, для типа, интервал ожидания которого может иметь только односекундные приращения, должно применяться округление тайм-аута до ближайшей секунды. Исключением из этого правила является округление значения в меньшую сторону до нуля. В этом случае тайм-аут должен округляться вверх до минимально возможного значения. Округление до ненулевого значения предотвращает возникновения циклов вида "занят ожиданием", когда нулевое значение тайм-аута приводит к 100-процентной загрузке процессора.
Кроме того, по истечении тайм-аута рекомендуется генерация исключения вместо возврата кода ошибки. Истечение тайм-аута означает, что операция не могла быть успешно завершена, и, следовательно, оно должно рассматриваться и обрабатываться как любая другая ошибка времени выполнения. Дополнительные сведения см. в разделе Правила разработки исключений.
При первом обращении к результатам асинхронной операции с тайм-аутом следует вызвать функцию обратного вызова и сгенерировать исключение. Это показано в следующем примере кода.
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));
}
Фрагменты — © Корпорация Майкрософт (Microsoft Corp.), 2005. Все права защищены.
Фрагменты — © Addison-Wesley Corporation. Все права защищены.
Для дополнительной информации о разработке руководящих принципов, смотрите "руководства по разработке рамок: Конвенций, идиомы и шаблоны для повторного использования.NET библиотек"книга, Кшиштоф Cwalina и Брэд Абрамс, опубликованных Addison-Wesley, 2005 года.