В приложении ASP.NET я много чего делаю с помощью Task.Run и Parallel.ForEach. В некоторые моменты я могу пройти 2-3 уровня в глубину:
// This is in a controller somewhere (i.e. so the Request object is in scope)
Task.Run(() => {
Parallel.ForEach(things, t => {
Task.Run(() => {
Parallel.ForEach(otherThings, t => {
// etc..
Это преувеличение (и глупая идея; я это понимаю), но вопрос в том, должен ли объект Request быть доступен на всем протяжении этого этапа?< /p>
Я много читал и понял, что ExecutionContext должен «перетекать» во весь этот код (если вы явно не запретите это).
Первый Task.Run должен получить тот же ExecutionContext, что и «внешний» код. Он должен передать это первому Parallel.ForEach и так далее. Насколько я понимаю, код в самом низу этого стека должен иметь доступ к тем же данным, что и исходный вызывающий код.
В моей ситуации я получаю странные нулевые ошибки на некоторых уровнях, когда ясно, что блок не получил переданный ему ExecutionContext. Например, внутри Task.Run все имеет значение null, но вне его не имеет значения null. Ошибки соответствуют определенному коду, но я не вижу, чем этот код отличается от другого кода, в котором ошибка не возникает.
Я неправильно понимаю некоторые нюансы ExecutionContext поток?
Обновление: Вот какой-то глупый, надуманный код:
void Main()
{
var things = new string[] { "foo", "bar", "baz" };
Console.WriteLine(1);
Task.Run(() =>
{
Console.WriteLine(2);
Parallel.ForEach(things, t =>
{
Console.WriteLine(3);
Task.Run(() =>
{
Console.WriteLine(4);
Parallel.ForEach(things, t =>
{
Console.WriteLine(5);
Console.WriteLine(t);
});
});
});
});
}
Конечно, я получаю выходные данные глубиной пять уровней. Таким образом, самый внутренний Parallel.ForEach содержит правильные данные в вещах (которые были установлены в вызывающем коде).
Что может привести к тому, что этого не произойдет?
Обновление: Основываясь на комментарии, я проверил теорию о том, что запрос завершался раньше, пока Задача все еще выполнялась. Я думаю, именно это и происходит, потому что я не использовал async/await. Это означало, что запрос не дождался завершения задачи, и объект Request исчез.
Вот мой тестовый код, КОТОРЫЙ РАБОТАЕТ (то есть, в этом конкретном тестовом примере он продолжает работать). навсегда...)
[Route("test")]
public async Task Test()
{
await Task.Run(() =>
{
var counter = 0;
while (true)
{
counter++;
ServiceLocator.Current.GetInstance().HttpContext.Items.Add(counter.ToString(), "foo");
Debug.WriteLine(counter);
}
});
return "OK";
}
Это НЕ работает — при попытке работы с HttpContext выдается нулевая ссылка. Поскольку я не ждал завершения задачи, она пыталась запуститься после завершения запроса, а запрос был нулевым.
[Route("test")]
public string Test()
{
Task.Run(() =>
{
var counter = 0;
while (true)
{
counter++;
ServiceLocator.Current.GetInstance().HttpContext.Items.Add(counter.ToString(), "foo");
Debug.WriteLine(counter);
}
});
return "OK";
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... el-foreach
Всегда ли ExecutionContext переходит в Task.Run или Parallel.ForEach? ⇐ C#
Место общения программистов C#
1733253958
Anonymous
В приложении ASP.NET я много чего делаю с помощью Task.Run и Parallel.ForEach. В некоторые моменты я могу пройти 2-3 уровня в глубину:
// This is in a controller somewhere (i.e. so the Request object is in scope)
Task.Run(() => {
Parallel.ForEach(things, t => {
Task.Run(() => {
Parallel.ForEach(otherThings, t => {
// etc..
Это преувеличение (и глупая идея; я это понимаю), но вопрос в том, должен ли объект Request быть доступен на всем протяжении этого этапа?< /p>
Я много читал и понял, что ExecutionContext должен «перетекать» во весь этот код (если вы явно не запретите это).
Первый Task.Run должен получить тот же ExecutionContext, что и «внешний» код. Он должен передать это первому Parallel.ForEach и так далее. Насколько я понимаю, код в самом низу этого стека должен иметь доступ к тем же данным, что и исходный вызывающий код.
В моей ситуации я получаю странные нулевые ошибки на некоторых уровнях, когда ясно, что блок не получил переданный ему ExecutionContext. Например, внутри Task.Run все имеет значение null, но вне его не имеет значения null. Ошибки соответствуют определенному коду, но я не вижу, чем этот код отличается от другого кода, в котором ошибка не возникает.
Я неправильно понимаю некоторые нюансы ExecutionContext поток?
[b]Обновление:[/b] Вот какой-то глупый, надуманный код:
void Main()
{
var things = new string[] { "foo", "bar", "baz" };
Console.WriteLine(1);
Task.Run(() =>
{
Console.WriteLine(2);
Parallel.ForEach(things, t =>
{
Console.WriteLine(3);
Task.Run(() =>
{
Console.WriteLine(4);
Parallel.ForEach(things, t =>
{
Console.WriteLine(5);
Console.WriteLine(t);
});
});
});
});
}
Конечно, я получаю выходные данные глубиной пять уровней. Таким образом, самый внутренний Parallel.ForEach содержит правильные данные в вещах (которые были установлены в вызывающем коде).
Что может привести к тому, что этого не произойдет?
[b]Обновление:[/b] Основываясь на комментарии, я проверил теорию о том, что запрос завершался раньше, пока Задача все еще выполнялась. Я думаю, именно это и происходит, потому что я не использовал async/await. Это означало, что запрос не дождался завершения задачи, и объект Request исчез.
Вот мой тестовый код, КОТОРЫЙ РАБОТАЕТ (то есть, в этом конкретном тестовом примере он продолжает работать). навсегда...)
[Route("test")]
public async Task Test()
{
await Task.Run(() =>
{
var counter = 0;
while (true)
{
counter++;
ServiceLocator.Current.GetInstance().HttpContext.Items.Add(counter.ToString(), "foo");
Debug.WriteLine(counter);
}
});
return "OK";
}
Это НЕ работает — при попытке работы с HttpContext выдается нулевая ссылка. Поскольку я не ждал завершения задачи, она пыталась запуститься после завершения запроса, а запрос был нулевым.
[Route("test")]
public string Test()
{
Task.Run(() =>
{
var counter = 0;
while (true)
{
counter++;
ServiceLocator.Current.GetInstance().HttpContext.Items.Add(counter.ToString(), "foo");
Debug.WriteLine(counter);
}
});
return "OK";
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79248199/does-executioncontext-always-flow-into-a-task-run-or-a-parallel-foreach[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия