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

时间:2014-10-27 09:46:42

标签: c# asp.net-mvc websocket signalr signalr-hub

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

我读了this article,我认为可以在异步方法中使用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();
    }

我尝试调用这样的方法:

 var appHub = $.connection.appHub;
 $.connection.hub.start();
 appHub.server.getServerTime()
              .done(function (time) {
                    alert(time);
               });

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

2 个答案:

答案 0 :(得分:11)

你可以use progress,因为:

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

另外,在服务器端使用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();
}

如果服务器端方法具有真正的异步工作(通常是I / O绑定操作),则它们应该只是async。作为一般规则,请避免服务器端的Task.Run

答案 1 :(得分:0)

在您的javascript中添加以下客户端方法

 var appHub = $.connection.appHub;
  $.connection.hub.start();
  appHub.client.progress = function(progresspct) {
     // logic for whatever you want to do.
  };

  appHub.server.getServerTime()
          .done(function (time) {
                alert(time);
           });

将服务器端代码修改为 -

    public async Task<string> GetServerTime(IProgress<int> prog)
   {
    await Task.Run(() => {
        for (int i = 0; i < 10; i++)
        {
            prog.Report(i * 10);
            // Call to your client side method.
            Clients.Client(Context.ConnectionId).progress(i);
            System.Threading.Thread.Sleep(200);
        }
    });

    return DateTime.Now.ToString();
}