#javascript #c# #signalr
#c# #asp.net-mvc #websocket #signalr #signalr-концентратор
Вопрос:
У меня есть класс 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);
});
Но я не знаю, как я могу получить отчеты о ходе выполнения.
Комментарии:
1. Привет, вы должны создать экземпляр IProgress на клиенте и передать его функции getServerTime. Затем вы регистрируетесь на событие в IProgress на клиенте, чтобы делать свои вещи
2. Спасибо, как я могу создать экземпляр на клиенте ?!
Ответ №1:
Вы можете использовать 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
код, привязанный к процессору, на стороне сервера. Ваш серверный код с таким же успехом может быть:
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
в том случае, если они выполняют настоящую асинхронную работу (обычно операции, связанные с вводом-выводом). Как правило, избегайте Task.Run
на стороне сервера.
Комментарии:
1. Сначала я получил сообщение об ошибке, в котором говорится, что метод progress является неопределенным типом, затем я заменил jquery 1.6.4 , который я использовал, на jquery 1.11.1 , так что теперь он работает! спасибо @Stephen Cleary 🙂
2. Та же идея, что и @Stephen Cleary, рекомендованная в примере Дэмианом Эдвардсом / SignalR-2.x-demo github.com/DamianEdwards/SignalR-2.x-demo/blob/master/SignalR2x /…
3. Просто небольшое замечание относительно использования
async
на сервере в концентраторах SignalR. В документации SignalR есть очень четкие указания по этому поводу: асинхронный метод концентратора позволяет избежать блокировки соединения при использовании транспорта WebSocket. Когда метод концентратора выполняется синхронно, а транспорт является WebSocket, последующие вызовы методов на концентраторе от того же клиента блокируются до завершения метода концентратора.
Ответ №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();
}