web-dev-qa-db-de.com

Fortschrittsbalken für Serveraufrufe mit langer Laufzeit in ASP.Net MVC

Ich möchte nur eine Fortschrittsleiste erstellen, während Serveraufrufe lange ausgeführt werden. Ich konnte keine Ajax-Post-Anforderung an den Controller erstellen, während der Controller einen langen Job ausführt. 

Ich möchte eine zusätzliche Aktion erstellen, um die tatsächliche Anweisung der aktuellen lang laufenden Aufgabe abzurufen. Ich habe versucht, eine Umfrage in einer Ajax-Anforderung zu erstellen. Dann kann ich den Status von der Serverseite zurückgeben und in einer clientseitigen Fortschrittsleiste anzeigen. Irgendwelche Ideen ? 

Der richtige und einfachste Weg dazu ist SignalR. Laden Sie Microsoft SignalR unter https://www.nuget.org/packages/Microsoft.AspNet.SignalR/2.1.2 herunter.

Erstellen Sie eine Hub-Klasse in einem separaten Ordner im Projektpfad, der als Hubs bezeichnet wird, und fügen Sie dem Hub-Ordner zwei Klassendateien hinzu

Startup.cs

using Owin;
using Microsoft.Owin;
[Assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

ProgressHub.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using Microsoft.AspNet.SignalR;

namespace RealTimeProgressBar
{
    public class ProgressHub : Hub
    {

        public string msg = "Initializing and Preparing...";
        public int count = 1;

        public static void SendMessage(string msg , int count)
        {
            var message = "Process completed for " + msg;
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
            hubContext.Clients.All.sendMessage(string.Format(message), count);
        }

        public void GetCountAndMessage()
        {
            Clients.Caller.sendMessage(string.Format(msg), count);
        }
    }
}

In der Steuerung

// assemblies
using Microsoft.AspNet.SignalR;
using RealTimeProgressBar;   


//call this method inside your working action
ProgressHub.SendMessage("initializing and preparing",  2);

Im Hinblick auf,

<!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
<!--Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!--SignalR script to update the chat page and send messages.--> 
<script type="text/javascript">
  $(document).ready(function () {

    $("#progressBar").kendoProgressBar({
        min: 0,
        max: 100,
        type: "percent",
    });
});

function StartInvoicing()
{
    var progressNotifier = $.connection.progressHub;

    // client-side sendMessage function that will be called from the server-side
    progressNotifier.client.sendMessage = function (message, count) {
        // update progress
        UpdateProgress(message, count);
        //alert(message);
    };

    // establish the connection to the server and start server-side operation
    $.connection.hub.start().done(function () {
        // call the method CallLongOperation defined in the Hub
        progressNotifier.server.getCountAndMessage();
    });
}

// Update the progress bar 
function UpdateProgress(message, count) {
    var result = $("#result");
    result.html(message);
    $("#progressBar").data("kendoProgressBar").value(count);
}
</script>

Weitere Informationen finden Sie in einigen vorhandenen Artikeln mit Hilfe von Google

Ich hatte einen langen Dienst dafür, ich habe unten eine Grundidee gegeben. Verwenden Sie es gemäß Ihren Anforderungen. 

  1. Ich habe eine Struktur der Fortschrittsargumente erstellt ProgressArgs
  2. Im lang laufenden Dienst LongRunningProcess () wurden die Fortschrittswerte in regelmäßigen Abständen aktualisiert und im JSON-Format in der Datenbank gespeichert
  3. Erstellt eine Action-Methode getProgress(), die einen Fortschritt der JSON-Zeichenfolge von ajax zurückgibt.
  4. Erstellt eine Funktion Javascript getProgress()-Funktion, die nach dem Start in regelmäßigen Abständen den Server anruft, um fortzufahren, bis der Vorgang abgeschlossen ist.

Ich habe ein grobes Beispiel gegeben, um es umzusetzen. Ich hoffe es kann dir helfen.

Die Struktur für die Klasse der Fortschrittsargumente

public class ProgressArgs
{
    public int Completed { get; set; }
    public int Total { get; set; }
    public int Percentage { get; set; }
    public string Status { get; set; }
}

Im Prozess habe ich ständig die Statistiken in der Datenbank aktualisiert

    public void LongRunningProcess()
    {

        ProgressArgs result = new ProgressArgs();
        result.Completed = 0;
        result.Total = userList.Count;
        foreach (var item in itemList)
        {
           //Do Some processing which u want to do

            result.Total++;
            result.Percentage = (result.Completed * 100) / result.Total;
            result.Status = "Processing";
            string strToSave = Newtonsoft.Json.JsonConvert.SerializeObject(result);
            //update the strToSave to the database somewhere.
        }

        //after completing of processing
        result.Total++;
        result.Percentage = (result.Completed * 100) / result.Total;
        result.Status = "Completed";
        string strToSave = Newtonsoft.Json.JsonConvert.SerializeObject(result);
        //update the strToSave to the database somewhere.

    }

Die C # Aktion, um den Fortschritt mit Ajax zu erhalten 

    public string getProgress()
    {    
        string strJSON = config.GetValue("progress");  //Get stats from the database which is saved in json
        return strJSON;
    }

Der Javascript-Code

//Ajax Get Progress function
    function getProgress() {
        var dataToSend = '';
        $.ajax({
            url: '@Url.Action("getProgress")', //Link to the action method
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: dataToSend,
            success: function (response) {
                console.log(response);
                if (response != null) {
                    data = JSON.parse(response);
                    console.log(data);
                    //update the progressbar
                    progressbar.progressbar("value", data.Percentage);
                    //When the jobalert status is completed clear the interval
                    if (data.Status == 0) {
                        setTimeout(getProgress, 800); //TImout function to call the respective function at that time
                    }
                    serviceCompleted(data); function to call after completing service
                }
            },
            error: function (xhr) {
                alert('Error: There was some error while posting question. Please try again later.');
            }
        });
    }
1
Pratik Bhoir