#c# #multithreading #thread-safety
#c# #многопоточность #безопасность потоков
Вопрос:
Вот как я вызываю эту функцию с учетом ошибки
var CrawlPage = Task.Factory.StartNew(() =>
{
return crawlPage(srNewCrawledUrl);
});
var GetLinks = CrawlPage.ContinueWith(resultTask =>
{
if (CrawlPage.Result == null)
{
return null;
}
else
{
return ReturnLinks(CrawlPage.Result, srNewCrawledUrl, srNewCrawledPageId);
}
});
Это ошибка, я действительно не понимаю, как это возможно. Я использую локальные присвоенные переменные, поэтому переменные должны быть потокобезопасными для всех потоков. Я не прав?
это изображение ошибки :
Комментарии:
1. Можете ли вы опубликовать полную трассировку стека?
2. как мне получить полную трассировку стека?
3. Где это ошибка, и где объявлены, используются и назначены srNewCrawledUrl и srNewCrawledPageId? В частности, есть ли цикл?
4. Марк Гравелл проверьте здесь: pastebin.com/VqGEmPcy и я полагаю, вы уже посмотрели изображение. он показывает ошибку.
5. @MonsterMMORPG Нажмите «Просмотреть детали …» в диалоговом окне на изображении.
Ответ №1:
перед вызовом вам лучше проверить, имеет ли innerHTML значение null или нет
var GetLinks = CrawlPage.ContinueWith(resultTask =>
{
if (CrawlPage.Result == null || CrawlPage.Result.DocumentNode == null || CrawlPage.Result.DocumentNode.InnerHtml == null)
{
return null;
}
else
{
return ReturnLinks(CrawlPage.Result, srNewCrawledUrl, srNewCrawledPageId);
}
});
Или проверьте это в методе ReturnLinks
Комментарии:
1. здравствуйте. вместо этого нет способа определить, является ли URL файлом или нет. это было бы намного лучше. я бы просто проигнорировал URL-адреса файлов.
2. также это все равно приведет к ошибке, потому что это просто то, что я делаю. я полагаю, что в Microsoft Visual Studio есть ошибка. потому что, когда я пытаюсь проверить, является ли внутренний html нулевым или нет, он выдает нулевое исключение. проверьте это изображение, оно объяснит больше: img824.imageshack.us/img824/3953/definitely.png при обходе файла он выдает ошибку.
3. правильный ответ заключается в том, что у этих методов есть внутренние методы, и они выдают ошибки.
Ответ №2:
Я использую локальные присвоенные переменные, поэтому переменные должны быть потокобезопасными для всех потоков. Я не прав?
Тот факт, что вы делаете ссылку локальной, не означает, что объект, на который указывает эта ссылка, внезапно становится локальным. Другой поток (не показан в вашем вопросе?) возможно, объект все еще изменяет HtmlDocument
объект в неподходящий момент (между hdDoc.DocumentNode != null
и hdDoc.DocumentNode.InnerHtml != null
).
Комментарии:
1. это локальная переменная. как другой поток может получить к нему доступ, объясните, пожалуйста. Спасибо.
2. @MonsterMMORPG
hdDoc
Является локальным, но он присваивается изDoc
которого являетсяReturnLinks
параметром метода, и я не знаю, откуда он взялся или какой другой поток может его использовать. Другими словами, только потомуHtmlDocument
, что на объект ссылается локальная ссылка в одном потоке, не означает, что на него также не ссылаются из какой-либо другой ссылки в каком-либо другом потоке. Вы несете ответственность за то, чтобы убедиться, что это не так или что доступ к этому объекту правильно сериализован через блокировку.3. хорошо, я понял вашу точку зрения. но здесь это не проблема, потому что проблема возникает при загрузке документа, отличного от html. но спасибо.