dot net:Express Edition Visual Studio 2008 でのスレッドの実行が遅すぎますか?
-
22-08-2019 - |
質問
私は12のスレッドを実行しています。これらのスレッドが呼び出している関数は、いくつかのオブジェクトにロックを持っていません。しかし、それでもこれらのスレッドには時間がかかりすぎます(16分)。各スレッドは個別に実行すると正常に実行されるXMLドキュメントを個別に解析します。この問題は、Express Edition によって提供される最大スレッド数に関連する何らかの理由、または Express Edition によってブロックされる DN が原因で発生します。
各スレッドが呼び出す関数のコードを以下に示します。各スレッドには異なる rssfeed(urladdress) が与えられます
public static class RssFileReader
{
public static Rss GetRssDocumentData(string rssFeed)
{
Console.WriteLine("thread in RssFileReader: " + Thread.CurrentThread.Name);
IFormatProvider culture = new CultureInfo("fr-FR", true);
Rss rssDocumentObject=new Rss();
XmlDocument documentObj = new XmlDocument();
try
{
documentObj.Load(HttpClient.GetWebResponse(@rssFeed, null, null, 1200000, @"http://www.sahil.com").GetResponseStream());
}
catch(Exception e)
{
e.Source = "RssFileReader:Loading xmldocument object";
throw;
}
try
{
XmlNodeList channelList = documentObj.GetElementsByTagName("channel");
for (int k = 0; k < channelList.Count; k++)
{
rssDocumentObject.ListOfChannel.Add(new Channel());
int noOfItemInChannel = -1;
//XmlNodeList itemList = channelList[k].ChildNodes;
for (int i = 0; i < channelList[k].ChildNodes.Count; i++)
{
switch (channelList[k].ChildNodes[i].Name)
{
case "item":
noOfItemInChannel++;
XmlNodeList xmlChildNodeOfItem = channelList[k].ChildNodes[i].ChildNodes;
//debugging
//Console.WriteLine("Thread Name in item in RssFileReader" + Thread.CurrentThread.Name);
rssDocumentObject.ListOfChannel[k].ListOfItem.Add(new Item());
for (int j = 0; j < xmlChildNodeOfItem.Count; j++)
{
switch (xmlChildNodeOfItem[j].Name)
{
case "title":
rssDocumentObject.ListOfChannel[k].ListOfItem[noOfItemInChannel].ItemTitle.InnerText = xmlChildNodeOfItem[j].InnerText;
break;
case "link":
rssDocumentObject.ListOfChannel[k].ListOfItem[noOfItemInChannel].ItemLink.InnerText = xmlChildNodeOfItem[j].InnerText;
break;
case "description":
rssDocumentObject.ListOfChannel[k].ListOfItem[noOfItemInChannel].ItemDescription.InnerText = xmlChildNodeOfItem[j].InnerText;
break;
case "pubDate":
try
{
string dateTimeTemp = xmlChildNodeOfItem[j].InnerText;
char[] splitCharArray = new char[1];
splitCharArray[0] = ' ';
string[] splitedDateTimeTemp = dateTimeTemp.Split(splitCharArray);
string RFC822 = "ddd,ddMMMyyyyHH:mm:ss";
rssDocumentObject.ListOfChannel[k].ListOfItem[noOfItemInChannel].ItemPubDate.PublicationDate = DateTime.ParseExact(splitedDateTimeTemp[0] + splitedDateTimeTemp[1] + splitedDateTimeTemp[2] + splitedDateTimeTemp[3] + splitedDateTimeTemp[4], RFC822, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
}
//exception not rethrown default date is assigned
catch (Exception e)
{
//Console.WriteLine("Exception while formatting string to datetime in rssFileReader():" + e);
}
break;
case "guid":
rssDocumentObject.ListOfChannel[k].ListOfItem[noOfItemInChannel].ItemGuid.InnerText = xmlChildNodeOfItem[j].InnerText;
break;
}
}
break;
case "title":
rssDocumentObject.ListOfChannel[k].ChannelTitle.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "description":
rssDocumentObject.ListOfChannel[k].ChannelDescription.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "link":
rssDocumentObject.ListOfChannel[k].ChannelLink.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "language":
rssDocumentObject.ListOfChannel[k].ChannelLanguage.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "pubDate":
try
{
string dateTimeTempForChannel = channelList[k].ChildNodes[i].InnerText;
char[] splitCharArrayForChannel = new char[1];
splitCharArrayForChannel[0] = ' ';
string[] splitedDateTimeTempForChannel = dateTimeTempForChannel.Split(splitCharArrayForChannel);
string formatStringForChannel = "ddd,ddMMMyyyyHH:mm:ss";
rssDocumentObject.ListOfChannel[k].ChannelPubDate.PublicationDate = DateTime.ParseExact(splitedDateTimeTempForChannel[0] + splitedDateTimeTempForChannel[1] + splitedDateTimeTempForChannel[2] + splitedDateTimeTempForChannel[3] + splitedDateTimeTempForChannel[4], formatStringForChannel, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
}
//exception not rethrown default date is assigned
catch (Exception e)
{
//Console.WriteLine("Exception while formatting string to datetime in rssFileReader():" + e);
}
break;
case "lastBuildDate":
try
{
string dateTimeTempForChannel = channelList[k].ChildNodes[i].InnerText;
char[] splitCharArrayForChannel = new char[1];
splitCharArrayForChannel[0] = ' ';
string formatStringForChannel = "ddd,ddMMMyyyyHH:mm:ss";
string[] splitedDateTimeTempForChannel = dateTimeTempForChannel.Split(splitCharArrayForChannel);
rssDocumentObject.ListOfChannel[k].ChannelLastBuildDate.LastBldDate = DateTime.ParseExact(splitedDateTimeTempForChannel[0] + splitedDateTimeTempForChannel[1] + splitedDateTimeTempForChannel[2] + splitedDateTimeTempForChannel[3] + splitedDateTimeTempForChannel[4], formatStringForChannel, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
}
//exception not rethrown default date is assigned
catch (Exception e)
{
//Console.WriteLine("Exception while formatting string to datetime in rssFileReader():" + e);
}
break;
case "docs":
rssDocumentObject.ListOfChannel[k].ChannelDocs.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "generator":
rssDocumentObject.ListOfChannel[k].ChannelGenerator.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "managingEditor":
rssDocumentObject.ListOfChannel[k].ChannelManagingEditor.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "webMaster":
rssDocumentObject.ListOfChannel[k].ChannelWebMaster.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
case "ttl":
rssDocumentObject.ListOfChannel[k].ChannelTtl.InnerText = channelList[k].ChildNodes[i].InnerText;
break;
}
}
}
}
catch(Exception e)
{
e.Source = "RssFileReader:Reading xml document object data to rss object";
throw;
}
Console.WriteLine(" Thread out RssFilereader :" + Thread.CurrentThread.Name);
return rssDocumentObject;
}
}
注: - デバッグ中に、XML ドキュメントの読み込みに時間がかかることがわかりました。WebRequest オブジェクトの数に関してシステムに課せられる制限はありますか?
解決 2
これは私がテスト用コンソールアプリケーションからそれを実行していた時間を取っていました。 撮影した多くの時間FO理由はIOがあるため、デバッグ用のprint文をブロックします。
他のヒント
同じサーバーへの Web リクエストを使用している場合、それらはデフォルトで一度に 2 つの接続に制限されます。
この場合、応答と応答ストリームの破棄に失敗することになります。つまり、ガベージ コレクションが完了して接続が解放されて別の場所で使用できるようになるまで待機することになります。読み込みコードを次のように変更します。
try
{
// Removed unnecessary @ signs
using (WebResponse response = HttpClient.GetWebResponse(
rssFeed, null, null, 1200000, "http://www.sahil.com"))
using (Stream responseStream = response.GetResponseStream())
{
documentObj.Load(responseStream);
}
}
catch(Exception e)
{
e.Source = "RssFileReader:Loading xmldocument object";
throw;
}
Web 応答を閉じるだけで済み、応答を閉じることでストリームが処理される可能性もありますが、確実にしておいた方がよいでしょう。
同じサーバーへの接続を同時に使用しても、取得できるスレッドは 2 つだけです (デフォルトでは、非 ASP.NET の場合)。これを自分で変更できます ServicePointManager.DefaultConnectionLimit
または connectionManagement
構成ファイル要素)しかし、少なくともそうすれば、接続がアイドル状態になったり、ガベージコレクションを待ったりする間待つ必要はありません。