2014-10-27 3 views
4

У меня есть класс Hub, который имеет длительный метод работы, мне нужно отобразить индикатор выполнения во время работы.Отчет о ходе работы с использованием интерфейса SignalR и IProgress

Я читал 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); 
       }); 

Но я не знаю, как я могу получить отчеты о ходе работы.

+1

Привет, Вам нужно создать экземпляр на IProgress на клиенте и передать его функции getServerTime. Затем вы регистрируетесь на мероприятии на IProgress на клиенте, чтобы делать ваши вещи. – kdev

+0

Спасибо, как я могу создать экземпляр на клиенте ?! –

ответ

9

Вы можете 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 по коду с привязкой к процессору на сервере sid е. Ваш код на стороне сервера может так же легко быть:

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

серверных методы должны быть только async если они имеют истинную асинхронную работу, чтобы сделать (обычно I/O-связанные операции). Как правило, избегайте Task.Run со стороны сервера.

+2

Сначала я получил сообщение об ошибке ** progress ** method - неопределенный тип, затем я заменил ** jquery 1.6.4 **, который я использовал, с ** jquery 1.11.1 **, так что теперь он работает ! спасибо @ Stephen Cleary :) –

+0

Такая же идея, как @Stephen Cleary, рекомендуется в образце DamianEdwards/SignalR-2.x-demo https://github.com/DamianEdwards/SignalR-2.x-demo/blob/master/SignalR2x /Web/HubProgress/index.cshtml –

+0

Просто небольшая заметка об использовании 'async' на сервере в концентраторах SignalR. В [Документации SignalR] есть очень четкое руководство (http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server#asyncmethods): _ Создание метода хаба асинхронно избегает блокировки соединения при использовании транспорта WebSocket. Когда метод хаба выполняется синхронно, а транспорт - это WebSocket, последующие вызовы методов на концентраторе от одного и того же клиента блокируются до тех пор, пока не будет завершен метод хаба. –

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(); 
} 
Смежные вопросы