2017-01-21 7 views
2

У меня есть то, что я считаю основным веб-приложением MVC, EF6. У пользователя есть панель, в которой представлена ​​таблица, содержащая данные из двух разных систем баз данных. MSSQL и Informix (с использованием IBM.Data.Informix).dotMemory и отслеживание утечек памяти

С течением времени процесс IIS просто убирается у барана. Я схватил dotMemory, чтобы помочь мне попытаться найти его, но теперь попытаюсь выяснить, как читать эти данные.

Я покинул веб-страницу, и каждые 10 секунд появляется вызов Ajax, который возвращает новые данные.

4-й снимок был сделан через несколько часов после третьего. enter image description here

Сумма не соответствует указанным ниже цифрам, но что-то не так, как должно быть.

На картинке ниже показано, что я использую не более 10 мб с моим приложением.

enter image description here

Я также по-прежнему смотрит в кучу, но это не кажется, что это где большая чанк.

enter image description here enter image description here enter image description here

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

DatabaseManager

public class DatabaseManager : IDisposable 
{ 
    private bool disposed = false; 
    private SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true); 

    private PatientCheckinEntities db { get; set; } 

    private IfxConnection conn { get; set; } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    public DatabaseManager() 
    { 
     string ifxString = System.Configuration.ConfigurationManager.ConnectionStrings["ifx"].ConnectionString; 
     conn = new IfxConnection(ifxString); 
     db = new PatientCheckinEntities(); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposed) 
      return; 

     if (disposing) 
     { 
      handle.Dispose(); 

      IfxClose(); 
      conn.Dispose(); 
      db.Dispose(); 
     } 

     disposed = true; 
    } 

    private void IfxClose() 
    { 
     if (conn.State == System.Data.ConnectionState.Open) 
     { 
      conn.Close(); 
     } 
    } 

    private void IfxOpen() 
    { 
     if (conn.State == System.Data.ConnectionState.Closed) 
     { 
      conn.Open(); 
     } 
    } 

    public ProviderModel GetProviderByResourceID(string id) 
    { 
     ProviderModel provider = new ProviderModel(); 

     using (IfxDataAdapter ida = new IfxDataAdapter()) 
     { 
      ida.SelectCommand = new IfxCommand("SELECT description FROM sch_resource WHERE resource_id = ? FOR READ ONLY", conn); 
      IfxParameter ifp1 = new IfxParameter("resource_id", IfxType.Char, 4); 
      ifp1.Value = id; 
      ida.SelectCommand.Parameters.Add(ifp1); 

      IfxOpen(); 
      object obj = ida.SelectCommand.ExecuteScalar(); 
      IfxClose(); 
      if (obj != null) 
      { 
       string name = obj.ToString(); 

       provider.ResourceID = id.ToString(); 
       string[] split = name.Split(','); 

       if (split.Count() >= 2) 
       { 
        provider.LastName = split[0].Trim(); 
        provider.FirstName = split[1].Trim(); 
       } 
       else 
       { 
        provider.LastName = name.Trim(); 
       } 

       ProviderPreference pp = db.ProviderPreferences.Where(x => x.ProviderID.Equals(id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); 

       int globalWait = Convert.ToInt32(GetConfigurationValue(ConfigurationSetting.WaitThreshold)); 

       if (pp != null) 
       { 
        provider.Preferences.DisplayName = pp.DisplayName; 
        provider.Preferences.WaitThreshold = pp.WaitThreshold.HasValue ? pp.WaitThreshold.Value : globalWait; 
       } 
       else 
       { 
        provider.Preferences.WaitThreshold = globalWait; 
       } 
      } 
     } 

     return provider; 
    } 

    public List<PatientModel> GetCheckedInPatients(List<string> providers) 
    { 
     List<PatientModel> patients = new List<PatientModel>(); 

     foreach (string provider in providers) 
     { 
      List<PatientModel> pats = db.PatientAppointments 
         .Where(x => provider.Contains(x.ProviderResourceID) 
         && DbFunctions.TruncateTime(x.SelfCheckInDateTime) == DbFunctions.TruncateTime(DateTime.Now)) 
          .Select(x => new PatientModel() 
          { 
           Appointment = new AppointmentModel() 
           { 
            ID = x.AppointmentID, 
            DateTime = x.AppointmentDateTime, 
            ArrivalTime = x.ExternalArrivedDateTime 
           }, 
           FirstName = x.FirstName, 
           LastName = x.LastName, 
           SelfCheckIn = x.SelfCheckInDateTime, 
           Provider = new ProviderModel() 
           { 
            ResourceID = x.ProviderResourceID 
           } 
          }).ToList(); 

      patients.AddRange(pats.Select(x => { x.Provider = GetProviderByResourceID(x.Provider.ResourceID); return x; })); 
     } 

     using (IfxDataAdapter ida = new IfxDataAdapter()) 
     { 
      ida.SelectCommand = new IfxCommand("SELECT arrival_time::char(5) as arrival_time FROM sch_app_slot WHERE appointment_key = ? FOR READ ONLY", conn); 

      IfxOpen(); 
      foreach (PatientModel patient in patients) 
      { 
       ida.SelectCommand.Parameters.Clear(); 
       IfxParameter ifx1 = new IfxParameter("appointment_key", IfxType.Serial); 
       ifx1.Value = patient.Appointment.ID; 
       ida.SelectCommand.Parameters.Add(ifx1); 

       using (IfxDataReader dr = ida.SelectCommand.ExecuteReader()) 
       { 
        while (dr.Read()) 
        { 
         if (dr.HasRows) 
         { 
          string arrival = dr["arrival_time"].ToString(); 

          if (!string.IsNullOrWhiteSpace(arrival) && !patient.Appointment.ArrivalTime.HasValue) 
          { 
           PatientAppointment pa = new PatientAppointment(); 
           pa.AppointmentID = patient.Appointment.ID; 
           pa.AppointmentDateTime = patient.Appointment.DateTime; 
           pa.FirstName = patient.FirstName; 
           pa.LastName = patient.LastName; 

           string dt = string.Format("{0} {1}", patient.Appointment.DateTime.ToString("yyyy-MM-dd"), arrival); 
           pa.ExternalArrivedDateTime = DateTime.ParseExact(dt, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); 
           patient.Appointment.ArrivalTime = pa.ExternalArrivedDateTime; 
           pa.ProviderResourceID = patient.Provider.ResourceID; 
           pa.SelfCheckInDateTime = patient.SelfCheckIn; 

           db.PatientAppointments.Attach(pa); 
           db.Entry(pa).State = EntityState.Modified; 
           db.SaveChanges(); 
          } 
         } 
        } 
       } 
      } 
      IfxClose(); 
     } 


     patients = patients.Select(x => { x.Appointment.WaitedMinutes = (int)Math.Round(((TimeSpan)x.Appointment.ArrivalTime.Value.Trim(TimeSpan.TicksPerMinute).Subtract(x.SelfCheckIn.Trim(TimeSpan.TicksPerMinute))).TotalMinutes); return x; }).ToList(); 

     List<PatientModel> sorted = patients.Where(x => !x.Appointment.ArrivalTime.HasValue).OrderBy(x => x.SelfCheckIn).ThenBy(x => x.Provider.ResourceID).ToList(); 
     sorted.AddRange(patients.Where(x => x.Appointment.ArrivalTime.HasValue).OrderBy(x => x.Appointment.DateTime).ThenBy(x => x.Provider.ResourceID)); 

     return sorted; 
    } 

    private string GetConfigurationValue(string id) 
    { 
     return db.Configurations.Where(x => x.ID.Equals(id)).Select(x => x.Value).FirstOrDefault(); 
    } 
} 

Контроллер

[HttpPost] 
[Authorize] 
public ActionResult GetCheckedIn(List<string> provider) 
{ 
    DashboardViewModel vm = new DashboardViewModel(); 
    try 
    { 
     if (provider.Count > 0) 
     { 
      using (DatabaseManager db = new DatabaseManager()) 
      { 
       vm.Patients = db.GetCheckedInPatients(provider); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     //todo 
    } 
    return PartialView("~/Views/Dashboard/_InnerTable.cshtml", vm); 
} 

ответ

1

Ваше приложение потребляет много родной памяти, а не .NET памяти. Посмотрите, что потребление памяти в .NET составляет около 12 МБ и не интенсивно растет. Кажется, что вы не вызываете метод Dispose на некоторые объекты, которые используют встроенную память, например. объекты подключения к базе данных или что-то в этом роде. Проверьте количество таких объектов, если вы их не выпускаете, число будет постоянно расти.