Не удается обновить пользовательский интерфейс после завершения фоновой задачи в моем ASP.NET применение

0

Вопрос

Я запускаю длительную функцию в качестве фоновой задачи в своем asp.net применение. Перед завершением задачи основной поток завершается (я хочу, чтобы это было только так, так как, если я использую ключевое слово await и заставлю основной поток ждать завершения фоновой задачи, я получу сообщение об ошибке прокси-сервера

Ошибка прокси-сервера
Прокси-сервер получил неверный ответ от вышестоящего сервера, так как фоновая задача слишком длинная

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

Мой код звучит так:

protected void btnImport_Click(object sender, EventArgs e)
{
        var task = ImportThread();

        if (task.IsCompleted)
        {
            DisplaySuccess("Import success");
        }
        else
            DisplayError("Import failed");
}

private async Task<bool> ImportThread()
{
        try
        {
            var success = await Task<bool>.Run(() => new Manager().Import().ConfigureAwait(false);

            if (task.IsCompleted)
            {
                DisplaySuccess("Import success");
            }
            else 
            {
                DisplayError("Import failed");
            }
    
            return true;
}

Описанная выше асинхронная задача ожидает метода, описанного ниже, который присутствует в другом классе.

public bool Import()
{
    // some operations here
    return true;
}

После завершения этого метода управление возвращается в ImportThread() но код, написанный там для переопределения пользовательского интерфейса, не обновляет пользовательский интерфейс. Мне нужно обновить пользовательский интерфейс со статусом импорта. А также от ImportThread управление также не возвращается к методу события нажатия кнопки.

Пожалуйста, помогите мне любым способом обновить пользовательский интерфейс статуса импорта.

Примечание: Я пытался использовать Redirect.Response в ImportThread() чтобы обновить страницу, но это не сработало

asp.net async-await background-task c#
2021-11-23 19:55:22
2

Лучший ответ

1

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

У вас есть этот случай, когда веб-страница находится на рабочем столе пользователя:

enter image description here

Теперь предположим, что пользователь нажимает кнопку.

Теперь у вас есть это:

 var task = ImportThread();

    if (task.IsCompleted)

Итак, веб-страница открыта на сервере. Вы можете включить даже асинхронное ожидание, пока коровы не вернутся домой, но у вас ВСЕ ЕЩЕ ЕСТЬ ЭТО:

enter image description here

Таким образом, пока ваш код выполняется или ожидает, веб-страница ВСЕ ЕЩЕ НАХОДИТСЯ на стороне сервера. ТОЛЬКО до тех пор, пока код не завершится и не завершится, страница переходит на сторону клиента.

снова: Ваш код не может остановиться и не может ждать, пока что-то завершится, так как если это произойдет, то страница ОСТАНЕТСЯ на сервере до завершения обработки.

ТОГДА И ТОЛЬКО ТОГДА веб-страница возвращается на сторону клиента. Затем это происходит;

enter image description here

А затем СТРАНИЦА НА СТОРОНЕ СЕРВЕРА ВЫБРАСЫВАЕТСЯ ИЗ памяти, и все переменные класса УНИЧТОЖАЮТСЯ!!! Веб-сервер теперь ждет, когда ЛЮБОЙ ПОЛЬЗОВАТЕЛЬ отправит обратно страницу для обработки!!

Итак, если вам нужно запустить какой-то длительный процесс?

У вас есть несколько вариантов:

опубликуйте страницу, код позади запускается, код позади запускает НОВЫЙ поток, веб-страница возвращается на сторону клиента. В этот момент вам нужен таймер + какой-то тип вызова веб-метода (ajax), чтобы опросить или спросить сервер, завершен ли длительный процесс. И поскольку вызов ajax не использует никаких веб-элементов управления на этой странице или переменных класса страницы (помните, ЧТО ПОСЛЕ того, как веб-страница перемещается обратно на сторону клиента, веб-страница НЕ ЯВЛЯЕТСЯ НЕСУЩЕСТВУЮЩЕЙ на стороне веб-сервера в памяти, и ни ОДНА из переменных класса не существует). Итак, опять же, это в значительной степени означает какой-то таймер или, как уже отмечалось, код таймера + для вызова какого-либо метода ajax. и этому длительному процессу, скорее всего, придется использовать session (), так как вы не используете элементы управления или даже состояние просмотра.

И вам не обязательно использовать вызов ajax. Вы можете использовать простую процедуру на стороне клиента JavaScript с таймером, который говорит, что нажимает кнопку каждые 1 или 2 секунды, код запускается, и затем ему нужно будет получить статус этого продолжительного процесса (опять же, вероятно, из сеанса), а затем обновить дисплей. А затем вы также можете включить код для остановки таймера, когда статус изменится на "готово" или что-то еще.

Таким образом, код, лежащий в основе, не "обновляет" веб-страницу и не будет "обновлять" ее несколько раз. У вас есть ОДНА поездка туда и обратно, и код, лежащий в основе, должен работать быстро, должен завершиться, и вы даже не можете использовать команду "ЖДАТЬ", так как тогда страница будет ждать и ВСЕ равно застрянет на сервере.

Если вы хотите выйти за рамки простого подхода с таймером, который я часто использую?

Затем вам нужно принять и внедрить на свой веб-сайт что-то, предназначенное для этого типа случаев -

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

СигналР

https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#:~:text=What%20is%20SignalR%3F%20ASP.NET%20SignalR%20is%20a%20library,process%20of%20adding%20real-time%20web%20functionality%20to%20applications.

2021-11-23 21:28:35
0

Если вы хотите асинхронно уведомить пользователя (о завершении или сбое чего-либо, например задачи), вы можете использовать веб-push-уведомление (с помощью firebase messaging cloud) или сокеты SignalR. Когда вы используете фоновую задачу, вы теряете основной поток, и, к сожалению, нет возможности ответить соответствующему пользователю.

2021-11-23 20:31:11

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................