Dziwne zachowanie strony ASP.NET

0

Witam, napisałem stronę w ASP.NET http://jakub.skierniewice.com.pl/, mam pewien problem z mechanizmem statystyk. Gdy strona jest włączona na serwerze to statystyki działają poprawnie. Natomiast gdy strona po 20 minutach bezczynności się wyłączy, to wejście nowego użytkownika powoduje dodanie nie określonej liczby osób do statystyk. Nie mam pojęcia gdzie jest problem. Załączam kod mechanizmu odpowiedzialnego za te statystyki. Proszę o szybką pomoc:

using System;
using System.Web;
using System.Linq;
using JakubCMF.Models;
namespace JakubCMF
{
    public class StatisticsContext
    {
        private ApplicationDatabaseContext DatabaseContext { get; set; }
        private DateTime LocalDate { get; set; }
        private YearStatistics YearStatistics { get; set; }
        private MonthStatistics MonthStatistics { get; set; }
        private DayStatistics DayStatistics { get; set; }

        public void Update(HttpRequestBase Request, HttpResponseBase Response)
        {
            if (Request.Browser.Cookies)
            {
                if (Request.Cookies["LastVisit"] != null)
                {
                    LocalDate = Convert.ToDateTime(Request.Cookies["LastVisit"].Value);
                    if (LocalDate != DateTime.Today)
                    {
                        if (DateTime.Today.Year > LocalDate.Year)
                        {
                            YearStatistics.Hits += 1;
                            MonthStatistics.Hits += 1;
                            DayStatistics.Hits += 1;
                        }
                        else if (DateTime.Today.Month > LocalDate.Month)
                        {
                            MonthStatistics.Hits += 1;
                            DayStatistics.Hits += 1;
                        }
                        else if (DateTime.Today.Day > LocalDate.Day)
                        {
                            DayStatistics.Hits += 1;
                        }
                    }
                }
                else
                {
                    DayStatistics.Hits += 1;
                    MonthStatistics.Hits += 1;
                    YearStatistics.Hits += 1;
                }
                DatabaseContext.SaveChanges();
            }
            Response.Cookies["LastVisit"].Value = DateTime.Today.ToShortDateString();
            Response.Cookies["LastVisit"].Expires = DateTime.Today.AddYears(1);
        }
        public StatisticsContext()
        {
            try
            {
                DatabaseContext = new JakubCMF.Models.ApplicationDatabaseContext();
                LocalDate = DateTime.MinValue;
                YearStatistics = DatabaseContext.YearStatistics.FirstOrDefault(e => e.Year == DateTime.Today.Year);
                if (YearStatistics == null)
                {
                    YearStatistics = new YearStatistics()
                    {
                        Year = DateTime.Today.Year,
                        Hits = 1
                    };
                    DatabaseContext.YearStatistics.Add(YearStatistics);
                    DatabaseContext.SaveChanges();
                }
                MonthStatistics = YearStatistics.Months.FirstOrDefault(e => e.Month == DateTime.Today.Month);
                if (MonthStatistics == null)
                {
                    MonthStatistics = new MonthStatistics()
                    {
                        Month = DateTime.Today.Month,
                        Hits = 1
                    };
                    YearStatistics.Months.Add(MonthStatistics);
                    DatabaseContext.SaveChanges();
                }
                DayStatistics = MonthStatistics.Days.FirstOrDefault(e => e.Day == DateTime.Today.Day);
                if (DayStatistics == null)
                {
                    DayStatistics = new DayStatistics()
                    {
                        Day = DateTime.Today.Day,
                        Hits = 1
                    };
                    MonthStatistics.Days.Add(DayStatistics);
                    DatabaseContext.SaveChanges();
                }
            }
            catch
            {
                YearStatistics = null;
                MonthStatistics = null;
                DayStatistics = null;
            }
        }

        public long ShowTodayStatistics()
        {
            try
            {
                return DatabaseContext.DayStatistics.Single(e => e.Id == DayStatistics.Id).Hits;
            }
            catch
            {
                return 0;
            }
        }
        public long ShowAllStatistics()
        {
            try
            {
                return DatabaseContext.YearStatistics.Sum(e => e.Hits);
            }
            catch
            {
                return 0;
            }
        }
    }
}

A tu kod wywołujący w _Layout.cshtml:

    if (Session["FirstVisitToday"] == null)
    {
        StatisticsContext.Update(Request,Response);
        Session["FirstVisitToday"] = false;
    }
 
0

Używasz właściwości obiektu do obliczeń (np. LocalDate). Do tego celu używa się zmiennych lokalnych. Raczej nie ma to bezpośredniego związku z Twoim problemem, ale wiedz, że tak się nie robi, bo spowoduje to nieprzewidziane działanie, jeśli kiedyś będziesz chciał korzystać z obiektu wielowątkowo (a tak działa IIS).
Co się dzieje, jeśli dwa wątki naraz będą aktualizować statystyki na bazie?
Dodaj sobie jakieś logowanie tego, co się dzieje w aplikacji (np. przez NLog), będziesz miał szansę namierzyć źródło problemu na produkcji.

[edit]
Mam wrażenie, że korzystasz z obiektu statystyk jak z singletona, a tak zaprojektowana klasa nie nadaje się do tego (pamiętaj, IIS obsługuje żądania wielowątkowo!).

1 użytkowników online, w tym zalogowanych: 0, gości: 1