Спорадический "Метод 'get_Session' в типе из сборки не имеет реализации" - PullRequest
1 голос
/ 13 мая 2011

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

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

В чем может быть причина? Есть ли какие-либо инструменты трассировки / входа в систему, чтобы узнать?

Method 'get_Session' in type 'Orders.Data.SafeSessionStorage' 
from assembly 'Orders.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 
does not have an implementation." 

System.TypeLoadException: Method 'get_Session' in type 'Orders.Data.SafeSessionStorage' from assembly 'Orders.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at Orders.Web.MvcApplication.InitializeNHibernateSession()
   at Orders.Web.MvcApplication.<Application_BeginRequest>b__1d()
   at SharpArch.Data.NHibernate.NHibernateInitializer.InitializeNHibernateOnce(Action initMethod)
   at Orders.Web.MvcApplication.Application_BeginRequest(Object sender, EventArgs e)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Вот SafeSessionStorage. Это слегка измененная версия SharpArch для поддержки работы в фоновых потоках.

public class SafeSessionStorage : ISessionStorage
{
  [ThreadStatic]
  private static ISession _session;

  public ISession Session
  {
     get
     {
        HttpContext context = HttpContext.Current;
        if (context == null)
           return _session;
        else
        {
           ISession session = context.Items[factoryKey] as ISession;
           return session;
        }
     }
     set
     {
        HttpContext context = HttpContext.Current;
        if (context == null)
           _session = value;
        else
           context.Items[factoryKey] = value;
     }
  }

  public string FactoryKey
  {
     get { return factoryKey; }
  }

  public static void End()
  {
     if (_session != null)
        _session.Close();
     _session = null;
  }

  public void EndRequest()
  {
     ISession session = Session;

     if (session != null)
     {
        session.Close();
        HttpContext context = HttpContext.Current;
        if (context != null)
           context.Items.Remove(factoryKey);
        else
           _session = null;
     }
  }

  private string factoryKey = NHibernateSession.DefaultFactoryKey;
}

Вот где происходит ошибка:

  private void InitializeNHibernateSession()
  {
     NHibernateInitHelper.InitSession(safeSessionStorage,
        Server.MapPath("~/NHibernate.config"),
        Server.MapPath("~/bin/Orders.Data.dll"));
  }

Здесь InitSession ожидает ISessionStorage и передается SafeSessionStorage, поэтому я полагаю, что там, где проверка типов завершается неудачей. И я бы заподозрил версии сборок, но, как я уже сказал, он всегда работает для меня, а иногда работает для пользователя.

1 Ответ

1 голос
/ 25 мая 2011

Я бы лучше принял комментарий Сэхэ как ответ, но в любом случае. Проблема заключалась в исключении StackOverflowException из-за рекурсивных данных БД. Чтобы отладить это, мне пришлось добавить ведение журнала во многие строки внутри подозреваемого кода (ошибка произошла при доступе к службе SOAP и отображении данных с использованием БД), а затем проанализировать. Другой подход заключался в развертывании отладочной сборки (это сервер dev) и использовании WinDbg, который дал правильный код исключения 0xe053534f, чтобы я мог сосредоточиться на коде, который может вызвать это (рекурсивный метод LINQ для сбора связанных продуктов).

Недостаточно места на диске было побочным эффектом DW20.exe (др. Уотсон), потребляющего 1,5 ГБ места (и ЦП).

Просмотр событий немного помог, потому что он показал слишком общую ошибку «kernel32.dll, address 0x0000bee7», что может быть переполнением стека и может быть чем-то еще.

Получение «метод не имеет реализации» - это последняя информация, которую я ожидал бы получить от таких условий.

...