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

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

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

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

public async Task GetServerTime(IProgress 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); }); 

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

您可以使用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 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

在您的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 GetServerTime(IProgress 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(); }