Si potrebbe utilizzare Tasks per fare questo, ecco un esempio:
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;
}
}
Grazie a Guillaume per il suggerimento di usare un TimeoutException.
Ma come sottolinea Jim Mischel, questo non impedirà il completamento dell'attività, nel qual caso sarebbe meglio se fosse possibile modificare l'API che si sta chiamando, perché in tal caso si potrebbe fare pieno uso della classe CancellazioneToken che è stato creato per questo genere di cose.
Oltre a questo, l'unica altra soluzione rapida che posso pensare (che può essere sconsigliabile) sarebbe quella di avvolgere il metodo (o combinarlo) con qualcosa di simile:
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;
}
}
E poi chiamare utilizzando:
Await(() => AskAPI("http://some.uri"), 30000);
Dovresti essere in grado di modificare 'api.Query' per aggiungere la funzionalità di timeout. Dato che non hai fornito informazioni su ciò che è, è impossibile dirti come farlo. (Non c'è modo di timeout per la chiamata, in quanto non hai modo di interromperlo in base a ciò che hai postato qui.) –
@KenWhite api.Query non è nemmeno nel mio controllo. Vuoi dire senza modificarlo, non posso far scadere il metodo AskAPI? – jamesdeath123
Non posso rispondere, perché hai fornito esattamente tre righe di codice ('{}' non conta) totalmente fuori dal contesto, con assolutamente nessun'altra informazione. Sulla base di ciò che hai pubblicato, la risposta sarebbe "No, non puoi". –