使用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(); }