Почему при добавлении задач создаются новые экземпляры списка?

#c# #asp.net #async-await

#c# #asp.net #асинхронное ожидание

Вопрос:

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

У меня есть следующая структура:

 private List<Task> tasks = new List<Task>();
private SemaphoreSlim mutex = new SemaphoreSlim(1, 1);

// Simulate some work
private async Task MyWork()
{
    int t = 0;
    while (t < 5)
    {
        await Task.Delay(TimeSpan.FromSeconds(5));
        t   ;
    }
}

// Called in the button's eventhandler
public void DoWork()
{
    mutex.Wait();
    this.tasks.Add(Task.Run(() => MyWork());
    mutex.Release();
}
  

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

Почему это происходит вместо добавления каждой задачи в один и тот же экземпляр списка?

Комментарии:

1. можете ли вы добавить код, в котором вы создаете класс, содержащий ваш метод DoWork?

2. Итак, при нажатии пользователем кнопки отправляется запрос на стороне сервера, в котором вы добавляете задачу в список? Не будет ли каждый запрос на стороне сервера создавать новый контекст и, следовательно, новый список? Это может быть причиной того, что ваш список имеет длину 0 для начала. Попробуйте использовать статический / одноэлементный экземпляр и посмотрите, работает ли он

3. @sayahimad Конструктор для класса здесь ни с чем не взаимодействует.

4. @pmain8 вы часто создаете экземпляр своего класса?

5. @sayahimad Теоретически это может быть, но в моем тестировании я делаю это только один раз.

Ответ №1:

Когда ASP.NET получает новый запрос, он создает новый экземпляр вашей страницы. Вот почему вы всегда видите пустой список.

Что вам следует сделать, так это заставить ваш обработчик кнопок создать идентификатор запроса (например, Guid), вставить этот запрос в надежную очередь, а затем обновить состояние сеанса с помощью этого идентификатора запроса. Итак, вместо списка задач у вас есть список идентификаторов запросов (строк). Затем отдельный рабочий процесс считывает данные из этой очереди и выполняет фактическую работу. Наконец, страница «ожидание» должна проводить опрос до тех пор, пока все запросы не будут выполнены.