Sie Tasks dies zu tun, verwenden könnte, hier ein Beispiel:
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;
}
}
Dank Guillaume für das Vorschlagen einer Timeout zu verwenden.
Aber wie Jim Mischel hervorhebt, wird dies die Ausführung der Aufgabe nicht verhindern. In diesem Fall wäre es am besten, wenn Sie die API, die Sie aufrufen, modifizieren, denn dann können Sie die CancellationToken-Klasse voll nutzen was für diese Art von Dingen gemacht wurde.
Andere als die, die einzige andere schnelle Lösung, die ich denken kann (was nicht ratsam sein kann) wäre, das Verfahren zu umwickeln (oder kombinieren) mit etwas wie folgt aus:
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;
}
}
Und dann rufen Verwenden:
Await(() => AskAPI("http://some.uri"), 30000);
Sie müssten in der Lage sein, 'api.Query' zu modifizieren, um Timeout-Funktionalität hinzuzufügen. Da Sie keine Informationen darüber haben, was es ist, ist es unmöglich, Ihnen zu sagen, wie es geht. (Es gibt keine Möglichkeit, um den Anruf herumzukommen, da Sie keine Möglichkeit haben, den Anruf aufgrund dessen, was Sie hier gepostet haben, zu unterbrechen.) –
@KenWhite api.Query ist auch nicht in meiner Kontrolle. Du meinst, ohne es zu bearbeiten, kann ich AskAPI-Methode nicht auslaufen? – jamesdeath123
Ich kann das nicht beantworten, weil Sie genau drei Codezeilen ('{}' zählt nicht) völlig außerhalb des Kontextes, mit absolut keinen anderen Informationen zur Verfügung gestellt haben. Basierend auf genau was du gepostet hast, wäre die Antwort "Nein, du kannst nicht". –