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.
RestoreFlow отменяет эффект предыдущего вызова метода SuppressFlow.
Этот метод вызывается методом Undo структуры AsyncFlowControl, возвращаемой методом SuppressFlow. Вы должны использовать метод Undo для восстановления потока контекста выполнения, а не метод RestoreFlow.
Акцент мой.
Я прочитал это - "Когда поток создан, среда выполнения гарантирует, что контекст выполнения инициирующего потока передается новому потоку. Таким образом, новый поток имеет те же привилегии, что и родительский поток. Такое копирование данных действительно стоит некоторых ресурсов, однако. Если вам не нужны эти данные, вы можете отключить это поведение с помощью метода ExecutionContext.SuppressFlow."
Источник: Программирование на C# Экзамен 70-483. Автор: Воутер де Корт
Когда поток создается, среда выполнения гарантирует, что контекст выполнения инициирующего потока передается в новый поток. Таким образом, новый поток имеет те же привилегии, что и родительский поток. Однако такое копирование данных стоит некоторых ресурсов. Если вам не нужны эти данные, вы можете отключить это поведение с помощью метода ExecutionContext.SuppressFlow.