Task.Delay () с большой задержкой в ​​Xamarin.iOS - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть особое требование, когда я должен вызывать фоновый поток после изменяющегося интервала времени в Xamarin.iOS бесконечно . Сначала я попытался реализовать его, используя класс Timer, как описано в на этой странице , но я не мог изменять интервал времени неограниченное количество раз.

Итак, я реализовал решение ниже:

void SomeUIMethod()
{
    while (true)
    {
        await Task.Run(PerformSync);
    }
}
...
private async Task PerformSync()
{
    var newInterval = SomeBackgroundTask();
    Task.Delay(newInterval*1000).Wait();
}

Это вызовет следующий поток после нового интервала времени, как я ожидал.

Теперь мои запросы, как показано ниже:

  1. Есть ли другой способ добиться этого, если большую часть времени Нить не находится в состоянии задержки?
  2. Влияет ли это на производительность приложения? учитывая, что в отложенном состоянии будет не более одного фонового потока.

1 Ответ

0 голосов
/ 07 сентября 2018

Task.Wait() - это не тот метод, который вы хотите использовать, когда у вас есть какие-либо альтернативы. Он синхронно блокирует асинхронную операцию, потребляя поток и, возможно, блокируя пользовательский интерфейс.

Вместо этого вы можете await the Task:

private async Task PerformAsync()
{
    while(true)
    {
        var newInterval = SomeBackgroundTask();
        await Task.Delay(newInterval * 1000);
    }
}

Это будет выполняться бесконечно, с задержкой между циклами, но поток освобождается после каждого цикла.

Кроме того, часто бывает проблематично что-то зацикливать навсегда . Вы, вероятно, хотите, чтобы это прекратилось в какой-то момент. Это хороший кандидат для использования CancellationToken, чтобы указать, что вы хотите отказаться от цикла.

private async Task PerformAsync(CancellationToken cancellationToken)
{
    try 
    {
        while(!cancellation.IsCancellationRequested)
        {
            var newInterval = SomeBackgroundTask();
            await Task.Delay(newInterval * 1000, cancellationToken);
        }
    }
    catch (OperationCanceledException ex) when (cancellation.IsCancellationRequested)
    {
        // Swallow the exception and exit the method.
    }
}
...