#c# #asp.net #linq-to-sql #.net-4.0 #parallel-processing
#c# #asp.net #linq-to-sql #.net-4.0 #параллельная обработка
Вопрос:
При запуске этого кода отображается следующая ошибка: «Ссылка на объект не установлена для экземпляра объекта» в первой строке возникает ошибка => MinorDBDataContext mdc = new
…
но также и с последовательным для «for(int i; i < 1005; i ) { } » работает нормально.
в чем проблема?
Thread.CurrentThread.Priority = ThreadPriority.Highest;
var query = from M in new MajorDBDataContext().User_Accounts select M;
List<User_Account> Ulist = query.ToList();
string d = DateTime.Now.ToString();
int c = 0;
string temp ="";
Parallel.For(0, 1005, (i,loop) =>
{
try
{
MinorDBDataContext mdc = new MinorDBDataContext(_Filings.OnServerRepository(Ulist[i].user_Sys_DBPath));
GoodJob(mdc, temp, i);
DA.Page page = mdc.Pages.Single();
temp = mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Email;
temp = mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Name;
temp = mdc.Minor_Users.Take(1).SingleOrDefault().Minor_User_Family i.ToString();
}
catch { }
});
append(temp);
Комментарии:
1. Рассмотрите возможность использования StringBuilder вместо String для этого.
2. Использование StringBuilder, вероятно, не решит проблему, заключающуюся в том, что все несколько потоков одновременно добавляются в StringBuilder, что приводит к несогласованному состоянию в StringBuilder или поврежденным строкам. Отдельные операторы Append в StringBuilder, скорее всего, будут применяться в лучшем случае не по порядку.
3. @Colin: Извините, я не пытался дать ответ на проблему. Я просто указал на то, что объединение строк здесь не приведет к чуду производительности. Я должен был прояснить это. Спасибо.
Ответ №1:
Ваше исключение может свидетельствовать о других вещах. Какое значение на самом деле null
? ты не говоришь.
Я вижу некоторые проблемы с этим кодом.
Вы не можете зависеть от последовательности выполнения цикла, но у вас есть temp =
(последовательное добавление строки к существующей строке с последующим присвоением строки обратно исходной переменной) во всем распараллеленном коде. Температура устанавливается вне параллельного цикла. Это очень опасно. Неправильное использование общего состояния / данных / ресурсов является одной из наиболее распространенных ошибок в многопоточном коде.
значения temp могут добавляться не по порядку. В temp одновременно будет добавлено несколько элементов, и, таким образом, в temp может отсутствовать информация, поскольку temp перезаписывается из нескольких потоков.
Откуда _Filings
берется? Что это?
Возможно, вы захотите создать новый temp
string
внутри цикла и добавить все туда, добавляя final temp
к ConcurrentBag
(который вы создаете вне цикла) на каждой итерации. После этого, за пределами параллельного цикла, вы можете выполнить итерацию по ConcurrentBag
и получить build вашей окончательной строки в безопасной среде.
Обновление на основе комментария Comment:
System.Web.HttpContext.Current.Сервер.В многопоточном цикле используется MapPath, а HttpContext.Current равен нулю.
Причина этого в том, что вы сейчас находитесь в потоке, отличном от текущего HttpContext, поэтому он не может ответить вам ни на какие вопросы. Вам нужно будет либо передать контекст параллельной задаче, либо отдельные значения из нее. Я не знаю, насколько это опасно в параллельной среде.
HttpContext myContext = HttpContext.Current;
В вашем параллельном цикле используйте myContext
вместо HttpContext.Current
.
Я не рекомендую это, поскольку знание HttpContext
областей in (таких как уровень данных) создает ненужную связь и делает приложение очень сложным в обслуживании. Чтобы рекомендовать лучшее решение, потребовалось бы гораздо больше разбирать ваше приложение на части, чем это возможно при публикации на форуме. Однако на данный момент это должно заставить вас снова двигаться.
Комментарии:
1. _Filings. OnServerRepository возвращает файл .mdf для строки подключения DataContext. в этом проекте планировалось по 1 базе данных на пользователя [Разработка нескольких баз данных]. в этой функции System.Web.HttpContext.Current. Сервер. В многопоточном цикле используется MapPath, а HttpContext.Current равен нулю. Спасибо за вашу помощь