使用SignalR和IProgress接口的进度报告

Sae*_*med 5 c# asp.net-mvc websocket signalr signalr-hub

我有一个Hub类,它有一个长时间运行的方法,我需要在它工作时显示一个进度条.

我读过这篇文章,我认为可以在异步方法中使用IProgress接口来发送长时间运行的操作状态.

我写了一个像这样的方法:

    public async Task<string> GetServerTime(IProgress<int> prog)
    {
        await Task.Run(() => {
            for (int i = 0; i < 10; i++)
            {
                prog.Report(i * 10);
                System.Threading.Thread.Sleep(200);
            }
        });

        return DateTime.Now.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

我尝试调用这样的方法:

 var appHub = $.connection.appHub;
 $.connection.hub.start();
 appHub.server.getServerTime()
              .done(function (time) {
                    alert(time);
               });
Run Code Online (Sandbox Code Playgroud)

但我不知道如何获得进度报告.

Ste*_*ary 11

您可以这样使用progress:

var appHub = $.connection.appHub;
$.connection.hub.start().done(function() {
  appHub.server.getServerTime()
    .progress(function (update) { alert(update); })
    .done(function (time) { alert(time); });
});
Run Code Online (Sandbox Code Playgroud)

另外,Task.Run在服务器端使用CPU绑定代码没有意义.您的服务器端代码可以很容易:

public string GetServerTime(IProgress<int> prog)
{
    for (int i = 0; i < 10; i++)
    {
        prog.Report(i * 10);
        System.Threading.Thread.Sleep(200);
    }

    return DateTime.Now.ToString();
}
Run Code Online (Sandbox Code Playgroud)

您的服务器端方法应该只有在async他们有真正的异步工作时才进行(通常是I/O绑定操作).作为一般规则,请避免Task.Run在服务器端.

  • 起初我得到一个错误说**progress**方法是一个未定义的类型,然后我用**jquery 1.11.1**替换了**jquery 1.6.4**,所以现在它可以了!谢谢@Stephen Cleary :) (2认同)
  • 关于在 SignalR 集线器中的服务器上使用“异步”的小注意事项。[SignalR 文档](http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server#asyncmethods) 对此有非常明确的指导:_Making a Hub method异步避免使用 WebSocket 传输时阻塞连接。当 Hub 方法同步执行且传输方式为 WebSocket 时,同一客户端对 Hub 上方法的后续调用将被阻止,直到 Hub 方法完成为止。_ (2认同)