MVC进度栏将无法正常工作

丹尼尔·霍尔茨曼

我正在尝试取得进度栏。在服务器端,我创建了一个控制器,该控制器应获取进度值并将其存储在会话中。

在客户端,我创建了两个ajax请求。其中一个启动了我要监视的功能,而另一个仅检查进度。我的意思是,这就是我认为它将起作用的方式。但是它仅在完成时输出某些内容。

它只等待几秒钟,然后发出警报“完成!”。就这样。

有什么问题?也许我应该在控制器中创建新线程以监视进度阶段?

这是客户端代码:

function generate() {

    setTimeout(checkProgress, 400);
        $.ajax({
            type: "POST",
            url: "/PPTReport/Generate",
            async: true,
            success: function (text) {
                 console.log(text);

            },
            error:function() {
                 console.log("error! error!");
            }
        });

  }

function checkProgress() {

    var id = "reportProgress";

    $.ajax({
        type: "POST",
        url: "/PPTReport/GetProgress",
        async: true,
        data: "id="+id,
        success: function (data) {
            if (data.done) {
                 console.log('Done!');
            } else {
                 console.log('Progress at ' + data.percent + '%');
                console.log(data.percent);
                setTimeout(checkProgress, 100 );
            }

        },
        error: function() {
            console.log('ajax error');
        }
    });
}

这是服务器端代码

public class ProgressInfo
    {
        public int Percent { get; set; }
        public bool Done { get; set; }
    }

 public JsonResult GetProgress(string id)
        {
            ProgressInfo progress;
            if (string.IsNullOrEmpty(id)
                || (progress = Session[id] as ProgressInfo) == null)
            {
                return Json(new
                {
                    success = false
                });
            }
            if (progress.Done)
            {
                Session.Remove(id);
            }
            return Json(new
                {
                    success = true,
                    done = progress.Done,
                    percent = progress.Percent
                }
            );
        }


public JsonResult Generate(){
                    //init stuff 
                    //there are somtheing like that
                    ProgressInfo progress = new ProgressInfo();
                    progress.Percent = 0;
                    progress.Done = false;
                    if (tabs > 0)
                    {
                        FirstPage();
                        progress.Percent++;
                        Session["reportProgress"] = progress;
                        if (tabs > 1)
                        {
                            SecondPage();
                            progress.Percent++;
                            Session["reportProgress"] = progress;
                            if (tabs > 2)
                            {
                                ThirdPage();
                                progress.Percent++;
                                Session["reportProgress"] = progress;
                                if (tabs > 3)
                                {
                                   LastPage();
                                }
                             }
                         }
                     }
                   //what we've gonna return stuff etc 
         }

UPD:好吧,我终于做到了-我做了测试功能(几乎像例子中一样),下面是代码:

js:

 function doCalculation() {
            $.post('/PPTReport/DoCalculation/sas');
            setTimeout(pollProgress, 1000);
        }

        function pollProgress() {
            var progressID = "sas";
            $.post('/PPTReport/GetProgress/' + progressID, function (response) {
                if (!response.success) {
                    alert('Cannot find progress');
                    return;
                }
                if (response.done) {
                    alert('Done!');
                } else {
                    alert('Progress at ' + response.percent + '%');
                    setTimeout(pollProgress, 1000);
                }
            }, 'json');

}

服务器端:

public void DoCalculation(string id)
        {
            ProgressInfo progress = new ProgressInfo();
            if (!string.IsNullOrEmpty(id))
            {
                Session[id] = progress;
            }

            //periodicly update progress
            int i = 0;
            while(i == 0 && progress.Percent != 7600000340)
            {
                progress.Percent++;
                Thread.Sleep(1000);
            }
        }

        public JsonResult GetProgress(string id)
        {
            ProgressInfo progress;
            if (string.IsNullOrEmpty(id)
                || (progress = Session[id] as ProgressInfo) == null)
            {
                return Json(new
                {
                    success = false
                });
            }
            if (progress.Done)
            {
                Session.Remove(id);
            }
            return Json(new
            {
                success = true,
                done = progress.Done,
                percent = progress.Percent
            });
        }

但我等了超过一分钟,才第一次执行该操作! 在此处输入图片说明

为什么会发生?它只是调用简单函数,为什么要等待这么长时间?

斯卡里斯特

这是一个旧问题的实例,请参见此处:

http://msdn.microsoft.com/en-us/library/ms178581.aspx

对ASP.NET会话状态的访问是每个会话的独占,这意味着如果两个不同的用户发出并发请求,则将同时授予对每个单独会话的访问权限。但是,如果对同一会话提出了两个并发请求(通过使用相同的SessionID值),则第一个请求将获得对会话信息的互斥访问。仅在第一个请求完成后才执行第二个请求。(如果由于第一个请求超过了锁定超时而释放了对该信息的排他锁,则第二个会话也可以访问。)如果@ Page指令中的EnableSessionState值设置为ReadOnly,则该请求为只读会话信息不会导致会话数据互斥锁定。然而,

我认为您可以在SO上找到许多讨论此问题的帖子。这是一个:

异步控制器通过jQuery阻止ASP.NET MVC中的请求

这是一种解决方法:

在ASP.Net MVC中禁用每个请求的会话状态

确定添加一些(未经测试!)示例代码。这只是表明如何解决此问题:

public class myCache {

    private static Dictionary<string, ProgressInfo> _pinfos = new Dictionary<string, ProgressInfo>();
    private static readonly object _lockObject = new object();

    public static void Add(string key, ProgressInfo value)
    {
        lock (_lockObject)
        {
            if (!_pinfos.ContainsKey(key)) {
                _pinfos.Add(key, value);
            }
            else {
               _pinfos[key] = value;
            }

        }
    }

    public static ProgressInfo Get(string key) {
        if (_pinfos.ContainsKey(key)) {
          return _pinfos[key];
        }
        else {
          return null;
        }
    }

    public static void Remove(string key) {         
        lock (_lockObject)
        {
          if (_pinfos.ContainsKey(key)) {
             _pinfos.Remove(key);
          }
        }
    }
}




[SessionState(SessionStateBehavior.ReadOnly)]
public class TestController : AsyncController

    public void DoCalculation(string id)
        {
            ProgressInfo progress = new ProgressInfo();
            if (!string.IsNullOrEmpty(id)) {
                myCache.Add(id,progress);
            }

            //periodicly update progress
            int i = 0;
            while(i == 0 && progress.Percent != 7600000340)
            {
                progress.Percent++;
                Thread.Sleep(1000);
            }
        }

        public JsonResult GetProgress(string id)
        {
            ProgressInfo progress;
            if (string.IsNullOrEmpty(id)
                || (progress = myCache.Get(id)) == null)
            {
                return Json(new
                {
                    success = false
                });
            }
            if (progress.Done)
            {
                myCache.Remove(id);
            }
            return Json(new
            {
                success = true,
                done = progress.Done,
                percent = progress.Percent
            });
        }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Android进度栏无法正常工作

来自分类Dev

如果添加多个窗口(pyside),进度栏将无法正常工作

来自分类Dev

引导程序:进度栏加载无法正常工作

来自分类Dev

带有进度栏的组合框无法正常工作

来自分类Dev

为什么jQuery进度栏无法正常工作?

来自分类Dev

如何使进度栏正常工作?

来自分类Dev

重复-进度无法正常工作

来自分类Dev

倒数进度栏无法正常运行

来自分类Dev

Progressbar.js-SVG进度栏无法正常工作IE 11,10,9

来自分类Dev

Progressbar.js-SVG进度栏无法正常工作IE 11,10,9

来自分类Dev

Unity2D C#重新加载进度栏无法正常工作

来自分类Dev

导航栏无法正常工作

来自分类Dev

Android SeekBar进度无法正常工作?

来自分类Dev

WPF进度栏将无法正确对齐

来自分类Dev

如果添加多个窗口(pyside),进度条将无法正常工作

来自分类Dev

MVC @RenderPage无法正常工作

来自分类Dev

Python TKinter进度栏标签无法正常运行

来自分类Dev

导航栏下拉列表无法正常工作

来自分类Dev

Vim NERDTree +标签栏无法正常工作

来自分类Dev

文字转栏功能无法正常工作?

来自分类Dev

Aurelia导航栏VM无法正常工作

来自分类Dev

Bootstrap搜索栏过渡无法正常工作

来自分类Dev

导航栏在jQuery中无法正常工作

来自分类Dev

无法使操作栏中的SearchView正常工作

来自分类Dev

菜单栏无法正常工作

来自分类Dev

我的固定导航栏无法正常工作

来自分类Dev

HTML导航栏换行/无法正常工作

来自分类Dev

粘性导航栏无法正常工作

来自分类Dev

导航栏无法正常工作-Django