C# 使用信号器和IProgress接口的进度报告

C# 使用信号器和IProgress接口的进度报告,c#,asp.net-mvc,websocket,signalr,signalr-hub,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+

我有一个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();
    }
 var appHub = $.connection.appHub;
 $.connection.hub.start();
 appHub.server.getServerTime()
              .done(function (time) {
                    alert(time);
               });

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

在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();
}
公共异步任务GetServerTime(IProgress prog) { 等待任务。运行(()=>{ 对于(int i=0;i<10;i++) { 进度报告(i*10); //调用客户端方法。 Clients.Client(Context.ConnectionId).progress(i); 系统线程线程睡眠(200); } }); return DateTime.Now.ToString(); } 您可以:

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();
}
公共字符串GetServerTime(IProgress prog)
{
对于(int i=0;i<10;i++)
{
进度报告(i*10);
系统线程线程睡眠(200);
}
return DateTime.Now.ToString();
}

只有当服务器端方法有真正的异步工作(通常是I/O绑定操作)时,它们才应该是
async
。一般来说,避免执行
任务。在服务器端运行

您好,您必须在客户端的IProgress上创建实例,并将其交给getServerTime函数。然后在客户端上注册到IProgress上的事件来完成您的工作谢谢,我如何才能在客户端上创建实例?!起初我得到一个错误,说progress方法是未定义的类型,然后我用jQuery1.11.1替换了我使用的jQuery1.6.4,所以现在它可以工作了!感谢@Stephen Cleary:)与DamianEdwards/SignalR-2.x-demo在示例中推荐的@Stephen Cleary的想法相同,只是关于在SignalR集线器的服务器上使用
async
的一个小提示。关于它有非常明确的指导:使集线器方法异步可以避免在使用WebSocket传输时阻塞连接。当集线器方法同步执行且传输为WebSocket时,从同一客户端对集线器上的方法的后续调用将被阻止,直到集线器方法完成。