2015-10-22 4 views
0

У меня есть следующий метод API:C# HttpContext.Current.Items является недействительным в икре нити

public IHttpActionResult Post(LogModel value) 
{ 
     try 
     { 
      IDictionary items = HttpContext.Current.Items; 
      Thread thread = new Thread(() => LogSQL.LogDetail(items, value)); 
      thread.Start(); 

      return Ok(); 
     } 
     catch (Exception ex) 
     { 
      ... 
     } 
    } 

До удара контроллера, есть аутентификация и авторизация код вызывается, который сохраняет некоторые данные в HttpContext.Current. Предметы.

Для новой угрозы HttpContext.Current.Items имеет значение NULL, поэтому я передаю данные элементов из родительского потока, чтобы установить его в потоке дочернего элемента.

public static void LogDetail(IDictionary items, LogModel log) 
    { 
     var keys = (from System.Collections.DictionaryEntry dict in items 
          let key = dict.Key.ToString() 
          select key).ToList(); 

     foreach (var key in keys) 
     { 
      HttpContext.Current.Items[key] = items[key]; 
     } 

... }

Но это не работает. HttpContext.Current.Items имеет значение null и только для чтения, поэтому я никак не могу его установить.

Я могу передать парфюм «предметы» на все, что нужно данным в новом потоке, но пытаясь избежать его.

Любые идеи о том, как это решить? Любой трюк, который я мог бы использовать?

+0

Самым простым способом понять, почему вы не можете получить контекст на породившей нити, чтобы увидеть, что произойдет, когда вновь породило поток фактически не запускает выполнение кода до конца запроса - что бы вы ожидали, что «Ток» будет установлен в этот момент? –

ответ

1

HttpContext.Current привязан к потоку, обрабатывающему HTTP-запрос. Если вы создадите новый поток, у него не будет связанного с ним контекста.

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

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

Обратите внимание, что это несколько опасно появляться потоки во время обработки запроса HTTP, потому что

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

(Source, и хорошо читать на эту тему, включая более эффективные способы, чтобы сделать это)

+0

спасибо Эрик. Я боялся, что для меня не было никаких трюков. Эта ссылка действительно хорошо читается. Благодарю. – Alex