【问题标题】:Progress indicator for long running tasks in MVC 5MVC 5 中长时间运行任务的进度指示器
【发布时间】:2015-09-12 01:31:35
【问题描述】:

前言:我已经继续使用this as the basis for what I'm doing

我试图给我的用户一些提示,表明提交表单实际上在做某事。

我的想法与 YouTube 所做的非常相似...在页面顶部设置一个栏,在整个页面上扩大宽度,以反映正在执行的任务的完成进度。

这是提交表单的 jquery:

    // Task Progress Indication

    function update(taskId, status) {
        var e = $("#" + taskId);
        if (status != "Completed") {
            // increase the width of the progress indicator
            e.css("width", status);
        }
        else {
            e.hide();
        }
    }

    $("form").submit(function (e) {
        // start indicating progress
        e.preventDefault();
        $.post("Home/Start", {}, function (taskId) {

            // periodically update monitor
            var intervalId = setInterval(function () {
                $.post("Home/Progress", { id: taskId }, function (progress) {
                    if (progress >= 100) {
                        update(taskId, "Completed");
                        clearInterval(intervalId);
                    }
                    else {
                        update(taskId, progress + "%");
                    }
                });
            }, 100);
        });
        // end indicating progress

        // this is the post of the form to the Controller
        $.post($(this).attr("action"), $(this).serialize(), function (data) {
            if (!data.IsOK) { // this is some error handling that I need to fix still
                $("#modalTitle").html(data.Title);
                $("#modalMessage").html(data.Message);
                $("#modalDetail").html(data.Error).hide();
                $("#modalDialog").css("display", "block");
                $("#modalBackground").css("display", "block");
            }
            else {
                window.location.href = '@Url.Content("~/")';
            }
            return;
        });

        return false;
    });

在我的控制器上,我有以下 ActionResult 用于处理进度指示器的更新。

private static IDictionary<Guid, int> tasks = new Dictionary<Guid, int>();

public ActionResult Start()
{
    var taskid = Guid.NewGuid();
    tasks.Add(taskid, 0);

    Task.Factory.StartNew(() =>
    {
        for (var i = 0; i <= 100; i++)
        {
            tasks[taskid] = i; // update task progress
            Thread.Sleep(50); // simulate long running operation
        }
        tasks.Remove(taskid);
    });
    return Json(taskid);
}

public ActionResult Progress(Guid id)
{
    return Json(tasks.Keys.Contains(id) ? tasks[id] : 100);
}

我在这里可能大错特错,但我认为我在页面上看不到任何内容的原因是进度指示和表单提交之间没有链接。

如何通过将表单提交链接到进度指示来解决此问题?

【问题讨论】:

    标签: jquery asp.net-mvc


    【解决方案1】:

    我实现了类似的功能来提供反馈,同时将多个 ssrs pdf 输出合并到一个文件中。在此过程中,我必须向用户提供一些反馈。这很痛苦,但我了解到 .NET 喜欢序列化对会话的访问 的方式会干扰返回回调的方式。您可能遇到了同样的问题。

    John Saunders 在这个question 中指出,我对这个问题的看法是简单地关闭客户端进度回发的控制器方法的会话状态。

    //IMPORTANT - NORMAL PROGRESS STATE SERIALIZES ACCESS TO SESSIONS - All callbacks are returned only after the controller method returns
    [SessionState(SessionStateBehavior.ReadOnly)]
    public class MyProgressCallbackClass
    {
        ...
    }
    

    【讨论】:

    • 虽然不能在函数声明上使用 SessionState 数据注释。显然它只允许在 Class 声明中......无论如何,这似乎已经解决了它。谢谢:)
    • 噢!它只是一个基于类的注释。
    • 现在,如何在所有内容上复制它(即 ActionLink 点击以及表单提交)嗯...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2015-02-03
    • 2019-08-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多