逾時用法
使用逾時來指定呼叫端願意等待方法呼叫完成的最長時間。
逾時可能採用方法呼叫的參數形式,如下所示。
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 的解析之型別,應該將逾時值四捨五入為可以容納的最近間隔。 例如,只能等待一秒鐘增量的型別應該四捨五入為最接近的秒鐘數。 這個原則的例外是當值將大略的四捨五入到零時。 在這種情況下,逾時應該盡可能化約到最小的逾時。 從零以外四捨五入可避免 busy-wait 迴圈,其中零的逾時值會造成處理器被百分之百利用。
此外,建議您當逾時過期時,擲回例外狀況代替傳回錯誤碼。 逾時的過期表示作業無法成功地完成,所以應該處理任何其他執行階段錯誤。 如需詳細資訊,請參閱例外狀況的設計方針。
在非同步作業與逾時的情況下,當先存取作業的結果時,應該呼叫回呼函式及擲回例外狀況。 這部分的說明在下列程式碼範例中。
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. All rights reserved.
Portions Copyright Addison-Wesley Corporation. All rights reserved.
設計指引的詳細資訊,請參閱"框架設計準則:公約、 成語和可重複使用的模式。網路圖書館"書 Krzysztof Cwalina 和布拉德 · 艾布拉姆斯,2005年艾迪生 - 衛斯理,發表。