#c# #php #multithreading #windows-phone-7 #webclient
#c# #php #многопоточность #windows-phone-7 #webclient
Вопрос:
Я столкнулся с немного запутанной проблемой, и я не уверен, заключается ли проблема в том, что я не знаю о делегате WebClient «OpenReadCompletedEvent», или проблема с выбранным мной решением, используемым в моих серверных скриптах, с которыми взаимодействует приложение.
Вот моя проблема:
У меня есть класс, который определяет название видеоигры, я использую WebClient для асинхронного открытия RSS-канала для чтения, который после завершения продолжает извлекать отправленную пользователем информацию об этом названии, используя тот же метод. Для этого я просматриваю каждое название видеоигры, проанализированное из RSS-канала (GameStop.com RSS-канал для предстоящих игр), вот где я сталкиваюсь с проблемами, у меня нет способа синхронизировать все эти делегаты OpenReadCompletedEvent, или ни одного, о котором я знаю.
Прямо сейчас мой код становится неудобным и запутанным, и я считаю, что это неправильно: Примечание: games — это список игровых объектов.
List<Thread> threads = new List<Thread>();
for(int i = 0; i < games.Count; i )
{
threads.Add(new Thread(downloadHype));
threads[i].Start(i);
}
public void downloadHype(object data)
{
int index = (int)data;
String tempUrl = String.Format("http://slyduck.com/hypemachine/frontend.php?intent=2amp;guid={0}", games[index].GuidString);
WebClient client = new WebClient();
client.OpenReadAsync(new Uri(tempUrl));
client.OpenReadCompleted = new OpenReadCompletedEventHandler(
delegate(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
XDocument xdoc = XDocument.Load(e.Result);
games[index].Hype = (from item in xdoc.Descendants("hype")
select new Hype()
{
Id = uint.Parse(item.Element("id").Value),
GameId = uint.Parse(item.Element("game_id").Value),
UserId = uint.Parse(item.Element("user_id").Value),
Score = (uint.Parse(item.Element("score").Value) == 1)
}).ToList();
}
});
}
Есть ли более простой способ для меня организовать это? Я рассматривал возможность отправки массива игровых идентификаторов guid в качестве параметра GET или POST, чтобы уменьшить часть мусора, генерируемого созданием такого количества веб-клиентов, но я не уверен, что это правильное решение.
Я изучил классы синхронизации и параллельные классы, однако они недоступны в реализации SilverLight .NET.
Буду признателен за любую помощь. Спасибо!
Ответ №1:
Вы порождаете слишком много потоков. Помните, что новый поток сразу же потребляет 1 МБ виртуального адресного пространства.
Если у вас есть один пользователь, у которого есть идентификатор (GUID), получите данные с помощью guid (как вы знаете), но ваш XML должен быть в виде списка шумихи, а не только одного.
Другими словами, используйте различную структуру XML. Тогда вам просто понадобится один поток backgroud и один WebClient для извлечения всего списка.
Комментарии:
1. Ну, сценарий, используемый выше, просто собирает все оценки hype для любой конкретной игры, выбранной с помощью идентификатора игры guid. Когда приложение запускается, мне нужно загрузить оценки hype, а также комментарии (выполненные аналогичным образом) для каждой игры, которая будет отображаться (обычно 15 в любой данный момент). Я мог бы отправить один запрос, чтобы получить ВСЕ рекламные объявления для ВСЕХ игр, а затем отсортировать их на C #, однако я ожидаю, что игры будут циклически обновляться на очень частой основе, поэтому извлечение ВСЕХ рекламных объявлений для ВСЕХ игр в конечном итоге приведет к массовым загрузкам.