2013-08-29 11 views
5

元のメソッド呼び出しは次のようです。タイムアウトメソッド呼び出し

今は、AskAPIメソッドにタイムアウト機能を追加したいので、api.Queryが30秒以上かかる場合、AskAPIは例外をスローします。

私はそれを働かせることができないようです。誰もがこれについての彼らの考えを共有することはできますか?

ありがとうございます!

+0

タイムアウト機能を追加するには、 'api.Query'を変更する必要があります。それが何であるかについての情報を提供していないので、その方法を教えることは不可能です。 (あなたがここに投稿したものに基づいてそれを中断する方法がないので、コールの周りをタイムアウトする方法はありません。) –

+0

@KenWhite api.Queryは私のコントロールにもありません。あなたはそれを編集せずに、私はAskAPIメソッドをタイムアウトすることができないのですか? – jamesdeath123

+0

私はこれに答えることができません。なぜなら、まったくコンテキストから完全に3行のコード( '{}'は数えません)を提供しているからです。正確に何を投稿したかに基づいて、答えは「いいえ、できません」となります。 –

答えて

8

あなたがこれを行うにはTasksを使用することができ、ここでの例です:TimeoutExceptionを使用することを示唆ためのギヨームへ

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; 
    } 
} 

感謝。

ジム・ミッシェルが指摘しているように、これでタスクが完了するのを止めることはありません。その場合は、CancellationTokenクラスを最大限に活用できるため、呼び出し元のAPIを変更できる場合に最適ですこのようなことのために作られたものです。

それ以外

、私はこのようなものでメソッドをラップ(またはそれを組み合わせる)ことであろう(勧められない場合もある)と考えることができる唯一の他の迅速な解決策:

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); 
+1

'Exception'を投げないでください。 'TimeoutException'を投げます。 – Guillaume

+1

@Guillaumeそのことをありがとう、私はそれを見て時間をかけていたはずです。 =) – sgbj

+2

しかし、タスクは実行し続けます。つまり、 'api.Query'は打ち切られませんか? –