Когда ЦП не подвержен влиянию использования «SemaphoreSlim.WaitAsync» и каковы альтернативы? - PullRequest
0 голосов
/ 05 декабря 2018

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

Моя цель - вызвать "restart", чтобы это произошло:

  • Запрос на выполнение всех задач
  • Ожидание завершения всех задач
  • Все функции запускаются снова

Я хочу использовать async / await и по-прежнему блокировать процесс запуска всех задач, чтобы быть уверенным, что ни один перезапуск не будет продолжен до предыдущего запуска/ рестарт закончен.

Как я видел по многим причинам, async / await не работает с блокировками состояний, поэтому в итоге я использую SemaphoreSlim, который прекрасно работает для меня.вот мой код:

private readonly SemaphoreSlim m_semaphoreSlim;
private CancellationTokenSource m_cancellationTokenSource;
private CancellationToken m_cancellationToken;

public FeedClientService(IList<IFeedConfigurationBuilder> feedConfigs)
{
    m_semaphoreSlim = new SemaphoreSlim(1, 1);
    m_feedConfigs = feedConfigs;
}

public void Start()
{
    Task.Run(() => this.FetchFeeds());
}

public void Restart()
{
    if (m_cancellationTokenSource != null) m_cancellationTokenSource.Cancel();

    Task.Run(() => this.FetchFeeds());
}

private async Task FetchFeeds()
{
    try
    {
        await m_semaphoreSlim.WaitAsync();

        m_cancellationTokenSource = new CancellationTokenSource();
        m_cancellationToken = m_cancellationTokenSource.Token;

        Task[] tasks = new Task[m_feedConfigs.Count];
        for (int i = 0; i < m_feedConfigs.Count; i++)
        {
            var index = i;
            tasks[index] = Task.Run(async () => await this.FetchFeed(index), m_cancellationToken);
        }

        await Task.WhenAll(tasks);
    }
    finally
    {
        m_semaphoreSlim.Release();
    }          
}

Как указано здесь https://stackoverflow.com/a/4154526/4664866 - «Класс SemaphoreSlim представляет собой легкий, быстрый семафор, который можно использовать для ожидания в одном процессе, когда время ожиданиякак ожидается, будет очень коротким ".Я не нашел ни одного источника, где указано, что означает «очень короткий», и я не уверен, что мой код не будет иметь узких мест в производительности, потому что задачи, которые я запускаю, наверняка не являются короткими.

TL; DR;

  • Что означает "очень короткое время ожидания"?
  • Что является альтернативой в случае, если время ожидания очень велико?

1 Ответ

0 голосов
/ 06 декабря 2018

Оказалось, что SemaphoreSlim.WaitAsync вообще не использует технику спин-ожидания (для справки - реализация SemaphoreSlim ).Таким образом, блокировка ресурсов, даже с долгосрочными задачами в них, не повлияет на загрузку процессора.

...