2015-02-15 4 views
2

Пожалуйста, см Антивибрационная мой кодAwait или тайм-аут на асинхронной операции

HttpResponseMessage messge = client.GetAsync("ladders/get/"+ID+").Result; 
if (messge.IsSuccessStatusCode) 
{ 
    string result = messge.Content.ReadAsStringAsync().Result; 
} 

Мне нужен этот код не выполнить до «результата» переменная не является нулевым или не более 30 минут. Каждую минуту будет выполняться следующий код до (result! = Null) в течение 30 минут.

Посмотрим, если не получите «результата» значение в течение 30 минут, затем через 30 мин функция будет автоматически остановить & уведомляет пользователя, что значение не найдено. Тем временем пользователь может получить доступ к другой странице.

Пожалуйста, предложите мне, как можно решить этот вопрос .....

+0

Рассмотрите возможность использования таймера здесь. Установите интервал в 1 минуту и ​​отмените таймер, если вы достигнете 30 минут или получите результат. Для ваших опций см. Https://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer. Я бы рекомендовал System.Threading.Timer для вашей цели. Также имейте в виду, что события тикового тика могут перекрываться, если ваш обработчик тиков занимает слишком много времени. – Warty

+0

Если мы говорим о веб-разработчике, подумайте о том, чтобы выполнить описанную выше логику с чем-то вроде setTimeout/setInterval, каждый месяц опросив веб-сервер. – Warty

ответ

4

я первый советую не блокировать с помощью .Result. API, выставленный HttpClient, является асинхронным по своей природе. Используя его, вы можете ввести тупики в свой код, который вы, вероятно, не хотите.

В принципе, то, что вы хотите реализовать, - это операция «первой задачи побеждает». Для этого, поскольку HttpClient.GetAsync уже возвращает Task, вы можете выполнить другую задачу, которая использует Task.Delay, которая внутренне использует таймер. И вы получите await в зависимости от того, какая из задач завершена первой:

public async Task GetAsync() 
{ 
    var expirationTimeTask = Task.Delay(TimeSpan.FromMinutes(30)); 
    var responseTask = client.GetAsync("ladders/get/ " + ID); 

    var finishedTask = await Task.WhenAny(expirationTimeTask, responseTask); 
    if (finishedTask == expirationTimeTask) 
    { 
     // If we get here, the timer passed 30 minutes 
    } 
    else 
    { 
     // If we get here, we got a response message first. 
     if (responseTask.IsSuccessStatusCode) 
     { 
      string result = await responseTask.Content.ReadAsStringAsync(); 
     } 
    } 
} 
+0

Вы также можете передать 'CancellationToken' в' GetAsync', который вы можете отменить, когда 'expirationTimeTask' будет выполнен первым. –

+0

@Jasd Ты прав. Но ОП, похоже, не нуждается в этом. Но его можно было легко добавить. –

Смежные вопросы