ASP MVC - Comet / Reverse Ajax / PUSH - Безопасен ли этот поток кода? - PullRequest
0 голосов
/ 10 января 2010

Я пытаюсь реализовать функции стиля кометы, опрашивая сервер на предмет изменений в данных и удерживая соединение открытым, пока не будет ответа.

Во-первых, у меня есть статическая переменная на контроллере, которая хранит время последнего обновления данных:

public static volatile DateTime lastUpdateTime = 0;

Поэтому, когда бы ни изменялись данные, которые я опрашиваю, эта переменная будет изменена.

У меня есть действие, которое принимает последний раз, когда данные были получены в качестве параметра:

public ActionResult Push(DateTime lastViewTime)
{
    while (lastUpdateTime <= lastViewTime)
    { 
        System.Threading.Thread.Sleep(10000);
    }
    return Content("testing 1 2 3...");
}

Таким образом, если lastUpdateTime меньше или равно lastViewTime, мы знаем, что новых данных нет, и мы просто храним запрос там в цикле, сохраняя соединение открытым, пока не появится новая информация, который мы могли бы затем отправить обратно клиенту, который обработает ответ и затем сделает новый запрос, так что соединение по существу всегда открыто.

Кажется, это работает нормально, но меня беспокоит безопасность потоков, это нормально? Нужно ли помечать lastUpdateTime как volatile? Есть ли лучший способ?

Спасибо

edit: возможно, мне следует использовать объект блокировки при обновлении значения времени

private static object lastUpdateTimeLock = new object();

..

lock (lastUpdateTimeLock)
{
    lastUpdateTime = DateTime.Now;
}

Ответы [ 2 ]

3 голосов
/ 11 января 2010

Относительно вашего исходного вопроса, вы должны быть осторожны с DateTimes, так как они являются реальными объектами во время выполнения .NET.Только несколько типов данных могут быть доступны непосредственно (например, int, bools) без блокировки (при условии, что вы не используете Interlocked).Если вы хотите избежать каких-либо проблем с Datetime, вы можете получить тики как длинные и использовать класс Interlocked для управления ими.

Тем не менее, если вы ищете возможности кометв приложении .NET, к сожалению, вам придется пойти намного дальше, чем у вас здесь.IIS / ASP.NET не будет масштабироваться с подходом, который вы используете сейчас;Вы достигнете пределов еще до того, как достигнете 100 пользователей.Помимо прочего, вам придется переключиться на использование асинхронных обработчиков и реализовать настраиваемый ограниченный пул потоков для входящих запросов.

Если вы действительно хотите протестировать решение для ASP.NET/IIS, посмотрите WebSync , это полноценный комет-сервер, разработанный специально для этой цели.

1 голос
/ 11 января 2010

Честно говоря, меня беспокоит количество открытых соединений и пустой цикл while. С соединениями у вас, вероятно, все в порядке, но я бы определенно хотел провести нагрузочное тестирование, чтобы убедиться.

Кажется, что while (lastUpdateTime <= lastViewTime) {} должно иметь Thread.Sleep(100) или что-то там. В противном случае я бы подумал, что это потребует много циклов ЦП без необходимости.

Блокировка мне не нужна в районе lastUpdateTime = DateTime.Now, так как предыдущее значение не имеет значения. Если бы это было lastUpdateTime = lastUpdateTime + 1 или что-то, то возможно было бы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...