使用 SignalR 和 IProgress 接口的进度报告
Posted
技术标签:
【中文标题】使用 SignalR 和 IProgress 接口的进度报告【英文标题】:Progress report using SignalR and IProgress interface 【发布时间】:2014-10-27 09:46:42 【问题描述】:我有一个 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);
);
但我不知道如何获得进度报告。
【问题讨论】:
您好,您必须在客户端的 IProgress 上创建实例并将其提供给 getServerTime 函数。然后你在客户端的 IProgress 上注册事件来做你的事情 谢谢,如何在客户端创建实例?! 【参考方案1】:您可以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
。
【讨论】:
起初我得到一个错误,说 progress 方法是一个未定义的类型,然后我将我正在使用的 jquery 1.6.4 替换为jquery 1.11.1,现在它可以工作了!谢谢@Stephen Cleary :) 与@Stephen Cleary 在 DamianEdwards/SignalR-2.x-demo github.com/DamianEdwards/SignalR-2.x-demo/blob/master/SignalR2x/… 的示例中推荐的想法相同 关于在 SignalR 集线器中的服务器上使用async
的小提示。 SignalR documentation 中对此有非常明确的指导:使 Hub 方法异步避免在使用 WebSocket 传输时阻塞连接。当 Hub 方法同步执行且传输为 WebSocket 时,从同一客户端对 Hub 上的方法的后续调用将被阻止,直到 Hub 方法完成。【参考方案2】:
在您的 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();
【讨论】:
以上是关于使用 SignalR 和 IProgress 接口的进度报告的主要内容,如果未能解决你的问题,请参考以下文章
.net core 3.0 Signalr - 02 使用强类型的Hub
.net core 3.0 Signalr - 02 使用强类型的Hub