ExecutionContext of Threads

Какова цель ExecutionContext.SuppressFlow();? В следующем коде что именно подавляется?

У меня есть этот тестовый код...

protected void btnSubmit_Click(object sender, EventArgs e)
{
   Thread[] th = new Thread[100];
   Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB");

   AsyncFlowControl cntrl = ExecutionContext.SuppressFlow();
   for (int i = 0; i < th.Length; i++)
   {                   
      th[i] = new Thread(new ParameterizedThreadStart(ThreadMethod));
      th[i].Name = "Thread #" + (i+1).ToString();                
      th[i].Start((i+1).ToString());
   }
   ExecutionContext.RestoreFlow();

   foreach (Thread t in th)            
   {
      t.Join();
   }
   Response.Write(response);
}


String response = null;
Random rnd = new Random(1000);
private void ThreadMethod(object param)
{   
   if (param != null)
   {
      string temp = param as string;
      if (temp != null)
      {
         //To test what is the current culture I get for this thread execution
         System.Globalization.CultureInfo info = Thread.CurrentThread.CurrentCulture;
         for (int i = 0; i <= 10; i++)
         {
            Thread.Sleep(rnd.Next(2000));
            response += Thread.CurrentThread.ManagedThreadId.ToString() + ":" 
                     + Thread.CurrentThread.Name + ": " + temp + "<br/>";
         }
      }
   }
}

5 ответов

Решение

Детали ExecutionContext очень неясны и скрыты внутри таких функций, как.NET Remoting и WCF. Что является частью этого:

  • HostExecutionContext
  • IllogicalCallContext, хранилище специфичных для потока данных, используемых Remoting
  • LogicalContext, как указано выше
  • SecurityContext
  • SynchronizationContext

CultureInfo не является его частью, что может стать серьезной проблемой, если вы измените стандартную культуру основного потока. Нет хорошего способа обеспечить работу других потоков с этой культурой, если вы явно не напишите код для их переключения. Это не всегда практично, учитывая, что.NET способен запускать асинхронные обратные вызовы в потоках пула потоков. Они будут инициализированы в культуре системы по умолчанию.

Изменить: эта проблема была исправлена ​​в.NET 4.5 с помощью свойства CultureInfo.DefaultThreadCurrentCulture.

Edit2: исправлено гораздо более тщательно в.NET 4.6, теперь культура работает так, как ожидалось.

ExcecutionContext. SuppressFlow подавляет поток контекста выполнения через асинхронные потоки.

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

ExecutionContext. RestoreFlow восстанавливает прохождение контекста исполнения между потоками.

в заключение

Q: В следующем коде что именно подавляется??

A: Точно подавляется прохождение следующей информации: контекст безопасности, контекст вызова и контекст синхронизации; между вновь созданными темами. Зачем это было делать? -Для оптимизации создания и работы потоков, созданных th.Length: меньше дополнительной информации, передаваемой между потоками - быстрее эти потоки взаимодействуют между ними.

Не ответ на ваш вопрос, но, поскольку вы просматриваете этот код и пытаетесь понять его прямо сейчас, пожалуйста, проверьте, хотите ли вы адаптировать / изменить свой код в соответствии с документацией (то есть "исправить это"):

ExecutionContext.SuppressFlow:

Вы должны использовать метод Undo в возвращенной структуре AsyncFlowControl, чтобы восстановить поток ExecutionContext.

ExecutionContext.RestoreFlow:

RestoreFlow отменяет эффект предыдущего вызова метода SuppressFlow.

Этот метод вызывается методом Undo структуры AsyncFlowControl, возвращаемой методом SuppressFlow. Вы должны использовать метод Undo для восстановления потока контекста выполнения, а не метод RestoreFlow.

Акцент мой.

Я прочитал это - "Когда поток создан, среда выполнения гарантирует, что контекст выполнения инициирующего потока передается новому потоку. Таким образом, новый поток имеет те же привилегии, что и родительский поток. Такое копирование данных действительно стоит некоторых ресурсов, однако. Если вам не нужны эти данные, вы можете отключить это поведение с помощью метода ExecutionContext.SuppressFlow."

Источник: Программирование на C# Экзамен 70-483. Автор: Воутер де Корт

Когда поток создается, среда выполнения гарантирует, что контекст выполнения инициирующего потока передается в новый поток. Таким образом, новый поток имеет те же привилегии, что и родительский поток. Однако такое копирование данных стоит некоторых ресурсов. Если вам не нужны эти данные, вы можете отключить это поведение с помощью метода ExecutionContext.SuppressFlow.

Другие вопросы по тегам