最初的方法調用是這樣的:定時進行的方法調用
public string AskAPI(string uri)
{
return api.Query(uri);
}
其中API是一個簡單的導入的DLL參考。
現在我想爲AskAPI方法添加超時功能,以便如果api.Query花費比30秒更長的時間,AskAPI將拋出一個異常。
似乎我無法讓它工作。任何人都可以分享他們的想法嗎?
謝謝!
最初的方法調用是這樣的:定時進行的方法調用
public string AskAPI(string uri)
{
return api.Query(uri);
}
其中API是一個簡單的導入的DLL參考。
現在我想爲AskAPI方法添加超時功能,以便如果api.Query花費比30秒更長的時間,AskAPI將拋出一個異常。
似乎我無法讓它工作。任何人都可以分享他們的想法嗎?
謝謝!
你可以使用Tasks要做到這一點,這裏有一個例子:
public string AskAPI(string uri, int millis)
{
using (var task = new Task<string>(() => api.Query(uri)))
{
task.Start();
task.Wait(millis);
if (!task.IsCompleted) throw new TimeoutException();
return task.Result;
}
}
感謝紀堯姆的建議使用一個TimeoutException。
但是正如Jim Mischel指出的那樣,這不會阻止任務完成,在這種情況下,如果您可以修改要調用的API,最好的辦法是使用CancellationToken類這是爲了這種事情而製作的。
除此之外,唯一的快速解決方案,我能想到的(可能是不可取的)將包裹方法(或結合起來),像這樣的東西:
public T Await<T>(Func<T> fun, int millis)
{
using (var cancel = new CancellationTokenSource(millis))
using (var task = new Task<T>(() =>
{
T result = default(T);
var thread = new Thread(() => result = fun());
thread.Start();
while (!cancel.Token.IsCancellationRequested && thread.IsAlive) ; // Wait for a sign from above
thread.Abort();
cancel.Token.ThrowIfCancellationRequested();
return result;
}, cancel.Token))
{
task.Start();
task.Wait(millis);
cancel.Cancel();
if (!task.IsCompleted) throw new TimeoutException();
return task.Result;
}
}
然後調用它使用:
Await(() => AskAPI("http://some.uri"), 30000);
你必須能夠修改'api.Query'來添加超時功能。由於您沒有提供關於它是什麼的信息,因此不可能告訴您如何執行此操作。 (沒有辦法在通話過程中超時,因爲根據你在這裏發佈的內容你無法中斷它。) –
@KenWhite api.Query也不在我的控制範圍之內。你的意思是沒有編輯它,我不能超時AskAPI方法? – jamesdeath123
我無法回答這個問題,因爲你已經提供了三行代碼('{}'不計算在內),完全沒有其他信息。根據你發佈的內容,答案將是「不,你不能」。 –