Session_End не гарантированно срабатывает - если вы, например, не используете сеансы InProc, он вообще не будет срабатывать. Если ваше приложение перезагружается или умирает, оно снова не сработает.
Лучше всего иметь этот код в общем методе, который можно вызывать из разных мест:
- В вашем LoginStatus элементе управления вы можете установить событие LoggingOut - вызовите свой метод там, чтобы обрабатывать людей, которые разумно выходят из системы.
- Если вы используете сеансы InProc, в своем событии Session_End, но не забудьте проверить, не вышли ли они из системы уже (как вы видели).
- Если вы не используете сессии InProc, вам нужно проявить немного больше творчества. Возможно, посмотрите на наличие события, которое запускается время от времени (возможно, на Session_Start, которое срабатывает независимо), которое проходит и очищает тех пользователей, которые в последний раз активнее времени превышают время ожидания сеанса (как упомянул Грег).
К сожалению, класс Членство дает вам некоторые полезные детали, но не все из них:
GetNumberOfUsersOnline
Будет «Получать количество пользователей, которые в данный момент обращаются к приложению». - отлично, но единственные методы, которые получат пользователи, либо:
GetAllUsers // Gets all the users from the storage provider (can be paged)
FindUsersByName
FindUsersByEmail
К сожалению, ни у одного из них нет свойства возвращать только "активных пользователей" согласно количеству.
Глядя на членов MembershipUser, нет свойства "IsOnline" - только LastLogonDate и LastActivtyDate - из-за отключенной природы сети, это, вероятно, так же хорошо, как вы собираетесь получить.