2017-11-08 11 views
0

私は非同期プログラミングでちょっと新しいので、多くのことを理解しないでください。私はもう少しお手伝いが必要です。私は私の他の質問で推薦されたようにしました。Funcの結果を取得<タスク<IResponse>>タイムアウトチェック中

public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync) 
{ 
     int timeout = 15; 
     if (await Task.WhenAny(sendAsync, Task.Delay(timeout) == sendAsync)) 
     { 
      return await sendAsync(); 
     } 
     else 
     { 
      throw new Exception("time out!!!"); 
     } 
} 

しかし、私はsendAsync()の結果を得てそれを返す必要があります。だから私は質問があります:

1)Task.DelayFunc<Task<TResponse>>(またはそれの代わりに何か)を使用するにはどうすればよいですか?私はどのように変換タスク(または何か)Funcタスクを把握することはできません。

2)もう一度permormsの要求がある場合はawait sendAsync()を返します。それは素晴らしいことではありません。どうにかして私のFunc<Task<..>>の結果を得ることができますか?

答えて

1

あなたは非同期プログラミングで新しく追加されたので - それはという1文と、より良い割りにあまりにも多くのものを入れない方が良いでしょう:私は申し訳ありませんが、あなたはどのような違いを説明することができ

public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync) { 
    int timeout = 15; 
    // here you create Task which represents ongoing request 
    var sendTask = sendAsync(); 
    // Task which will complete after specified amount of time, in milliseconds 
    // which means your timeout should be 15000 (for 15 seconds), not 15 
    var delay = Task.Delay(timeout); 
    // wait for any of those tasks to complete, returns task that completed first 
    var taskThatCompletedFirst = await Task.WhenAny(sendTask, delay); 
    if (taskThatCompletedFirst == sendTask) { 
     // if that's our task and not "delay" task - we are fine 
     // await it so that all exceptions if any are thrown here 
     // this will _not_ cause it to execute once again 
     return await sendTask; 
    } 
    else { 
     // "delay" task completed first, which means 15 seconds has passed 
     // but our request has not been completed 
     throw new Exception("time out!!!"); 
    } 
} 
+0

「if」内の「sendTaskを待つ」が2回目に実行されない理由を説明することもできますか?ちょっと魔法のようです。 – Amelina

+0

は何も実行しません。非常に簡略化された言葉では、「このタスクが実行されている間に、何か他のことをやって、タスクが完了したらここに戻り、残りのメソッドを実行し続ける」のようなものです。このタスクは既に完了しているので、例外があるかどうかを確認してスローします。 – Evk

+0

@Amelinaしかし、単純化された説明に頼るのではなく、async \ awaitについての記事を読んでください。 – Evk

1

sendAsyncがFuncを返すタスクで、各呼び出しごとに異なるため、要求が2回送信されます。最初にTask.WhenAny()の下に電話し、オペレーターreturn await sendAsync()を繰り返します。この重複を避けるために

は、変数にタスクを保存し、両方の呼び出しにそのタスクを渡す必要があります呼び出します。

完了したタスクの
public async Task<TResponse> SendRequestAsync<TResponse>(Func<Task<TResponse>> sendAsync) 
{ 
    int timeout = 15; 
    var task = sendAsync(); 
    if (await Task.WhenAny(task, Task.Delay(timeout) == task)) 
    { 
     return await task; 
    } 
    else 
    { 
     throw new Exception("time out!!!"); 
    } 
} 

awaitだけでタスクを再実行することなく、その結果を返します。

+2

? – Amelina

関連する問題