Pas en mesure de mettre à jour l'INTERFACE utilisateur après l'arrière-plan de l'achèvement de la tâche dans mon ASP.NET application

0

La question

Je suis en cours d'exécution d'une fonction longue durée en tâche de fond dans mon asp.net application. Avant que la tâche se termine le thread principal des sorties (je veux de cette façon seulement, car si j'utilise le mot clé await et de faire des thread principal attendre jusqu'au fond de fin de la tâche, je reçois proxy erreur avec le message

Erreur De Proxy
Le serveur proxy a reçu une réponse invalide à partir d'un serveur en amont depuis la tâche en arrière-plan est trop long

Mais une fois après l'achèvement de la tâche, ni que je suis en mesure d'actualiser la page en redirigeant vers la même page ou aucun des deux, je suis en mesure de remplacer l'INTERFACE utilisateur. Est-il possible de mettre à jour l'INTERFACE utilisateur après le thread principal de l'exécution terminée.

Mon code ressemble à ceci:

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;
}

Le ci-dessus async tâche qui attend la méthode ci-dessous, qui est présent dans une autre classe.

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

Après cette méthode est terminée, le contrôle de renvoyer dos à ImportThread() mais le code écrit pour remplacer l'INTERFACE utilisateur n'est pas la mise à jour de l'INTERFACE utilisateur. J'ai besoin de mettre à jour l'INTERFACE utilisateur avec l'état d'importation. Et aussi à partir de ImportThread le contrôle n'est pas de revenir à l'événement clic du bouton de la méthode de trop.

S'il vous plaît aidez-moi avec toutes les mise à jour de l'INTERFACE utilisateur de l'état d'importation.

Note: j'ai essayé d'utiliser Redirect.Response dans ImportThread() pour actualiser la page, mais cela ne fonctionne pas

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

La meilleure réponse

1

Votre problème est que vous avez à saisir et à comprendre la page web du cycle de vie ici.

Vous avez la présente affaire, où la page web est assis sur les utilisateurs de bureau:

enter image description here

Maintenant dire que l'utilisateur clique sur un bouton.

Vous avez maintenant ceci:

 var task = ImportThread();

    if (task.IsCompleted)

Ok, donc la page web est en place sur le serveur. Vous pouvez mettre dans le même async attend jusqu'à ce que les vaches viennent à la maison, mais vous AVEZ ENCORE CECI:

enter image description here

Donc, tant que votre code s'exécute, ou attend, la page web est TOUJOURS BLOQUÉ sur le côté serveur. SEULEMENT jusqu'à la fin du code et quitte la page de voyager vers le bas pour le côté client.

NOUVEAU: Votre code derrière ne peut s'arrêter, et ne peut pas attendre pour quelque chose à la fin, car si c'est le cas, la page RESTE en place sur le serveur jusqu'à ce que le traitement terminé.

ALORS, ET SEULEMENT ALORS, la page web de faire le voyage de retour vers le bas pour le côté client. Ensuite, cela se produit;

enter image description here

Et puis le CÔTÉ SERVEUR de la PAGE EST JETÉ HORS de la mémoire, et toutes les variables de classe sont DÉTRUITS!!! Le serveur web est maintenant en attente pour n'IMPORTE quel UTILISATEUR de publier une page de traitement!!

Donc, si vous avez besoin d'exécuter certains types de processus d'exécution long?

Vous avez un peu de choix:

afficher la page, le code derrière des pistes, le code derrière démarre un NOUVEAU thread, page web rend le voyage de retour à côté client. À ce stade, vous avez besoin d'un timer + un certain type de l'appel de la méthode web (ajax) à interroger ou de demander au serveur si le long processus en cours d'exécution est fait. Et depuis, un appel ajax ne PAS utiliser de contrôles web sur cette page ou la page de variables de classe (rappelez-vous, APRÈS que la page web se déplace vers le bas en arrière à côté client, la page web n'est PAS EXISTANTE web côté serveur dans la mémoire, ni de la classe des variables existantes). Donc, encore une fois, de ce fait beaucoup signifie une sorte de timer, ou comme l'a noté, d'une minuterie + code d'appel ajax méthode. et ce long processus en cours d'exécution devra TRÈS probablement session() puisque vous n'avez pas l'utilisation de commandes, ou même ViewState.

Et vous n'avez pas besoin d'utiliser un appel ajax. Vous pouvez utiliser un simple JavaScript côté client de routine avec un timer qui disent clique sur un bouton, tous les 1 ou 2 secondes, le code s'exécute derrière, et il aurait alors à obtenir le statut de ce long processus en cours d'exécution (de nouveau, probablement à partir de la session), puis mise à jour de l'affichage. Et puis vous pouvez également inclure le code pour arrêter le chronomètre lorsque le changement de statut "terminé" ou quoi que ce soit.

Donc le code derrière n'est pas et ne sera pas "mise à jour" de la page web à plusieurs reprises. Vous avez UN voyage aller-retour, et le code doit s'exécuter rapidement, doit terminer l'exécution, et ne peuvent même pas utiliser une ATTENDENT de commande, depuis la page STLL attendre, et ENCORE être bloqué sur le serveur.

Si vous voulez aller au-delà de la simple minuterie truc approche que j'utilise souvent?

Ensuite, vous devez adopter et à les introduire dans votre site web quelque chose conçu pour ce type de cas

Heureusement, il y a signalR à cette fin, et qui, sans aucun doute la meilleure option pour vous, car il est conçu pour exactement à votre question et de scénario.

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

Si vous souhaitez de manière asynchrone informer un utilisateur (de la réussite ou l'échec de quelque chose comme une tâche), vous pouvez utiliser web notification push (à l'aide de firebase de messagerie cloud) ou SignalR sockets. Lorsque vous utilisez une tâche en arrière-plan, vous perdez le thread principal et malheureusement, il n'existe aucun moyen de répondre à l'utilisateur.

2021-11-23 20:31:11

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................