Comments 18
автор вам, конечно, спасибо
но это не статья это исходный код с комментариями :)
один вопрос, может быть для данной задачи имеет смысл сделать загрузку фидов по таймеру (скажем раз в минуту), а не в бесконечном цикле с паузой потока? я спросил исключительно из-за фразы «наоболее оптимален в таких задачах», интересно почему наимболее оптимален?
но это не статья это исходный код с комментариями :)
один вопрос, может быть для данной задачи имеет смысл сделать загрузку фидов по таймеру (скажем раз в минуту), а не в бесконечном цикле с паузой потока? я спросил исключительно из-за фразы «наоболее оптимален в таких задачах», интересно почему наимболее оптимален?
Я все-таки видимо не удачный пример взял… обычно такую схему я использую для «уведомления» Web-сервисов, о наступлении каких-то событий в БД (новые данные, который нужно обработать и т.п.). Можно использовать и таймер, здесь просто пример циклом, как наиболее распространенный подход (которые я встречал).
А по поводу исходного кода я отметил отдельно, что в коментариях рассказывается как используются определенные элементы.
А по поводу исходного кода я отметил отдельно, что в коментариях рассказывается как используются определенные элементы.
Для «слежения» за бд есть штука — Sqldependency.
А еще есть Web-сервисы, с которых я получаю данные… Источник данных не важен, важно что данные там могут появится в любую минуту, и должны быть почти сразу обработаны. С другой стороны постоянные запросы к Web серверам, например, создадут ненужную нагрузку, но такие моменты можно всегда регулировать.
А теперь с использованием Parallel Extensions CTP:
Я не профессиональный .NET-разработчик, и код вполне может содержать фатальные недостатки по сравнению с примером в статье. Но концепция мне очень нравится :-)
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
namespace ParallelRSS
{
class Program
{
private static string ProcessRSS(string feedUrl)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(feedUrl);
var response = request.GetResponse();
return (new StreamReader(response.GetResponseStream())).ReadToEnd();
}
private static string[] GetURLs()
{
return new string[] {
"habrahabr.ru/rss/",
"www.cbr.ru/scripts/RssPress.asp"
};
}
static void Main(string[] args)
{
try
{
var data = GetURLs().AsParallel().Select(url => ProcessRSS(url));
foreach (string x in data)
{
Console.WriteLine(x);
}
}
catch (AggregateException e)
{
}
Console.Read();
}
}
}
* This source code was highlighted with Source Code Highlighter.
Я не профессиональный .NET-разработчик, и код вполне может содержать фатальные недостатки по сравнению с примером в статье. Но концепция мне очень нравится :-)
Для подобных задач намного лучше подходить ThreadPool. Когда потоки простые и однотипные, вы просто создаёте ThreadPool и размещаете в нём задания. Он сам парралелит на оптимальное или указанное число потоков ваши задания, и вам не надо следить за количеством тредов. + ресайклинг.
Подробно в MSDN
Вот собственно говоря, оттуда самый простой пример работы.
Подробно в MSDN
Вот собственно говоря, оттуда самый простой пример работы.
class MainApp
{
static void Main()
{
for(int i=0;i<30;i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(PoolFunc));
}
Console.ReadLine();
}
static void PoolFunc(object state)
{
int workerThreads,completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads,
out completionPortThreads);
Console.WriteLine("WorkerThreads: {0}, CompletionPortThreads: {1}",
workerThreads, completionPortThreads);
Thread.Sleep(15000);
ConnectionSocket connection = new ConnectionSocket();
connection.Connect();
}
}
* This source code was highlighted with Source Code Highlighter.
Так вы видимо не заметили, что для обработки каждого элемента данных и используется ThreadPool. Отдельный поток только для того, что бы не блокировался основной поток приложения.
Ну, вот как-то странно выходит. Главный поток не поточить через него?
Блин, из за вас теперь сижу в студии, и думаю, как оптимизировать 8-)))
С технической точки зрения — всё правильно. Спорно конечно про бесконечный цикл, но на это можно сейчас забить. Есть объекты синхронизации, правильные инкременты. Но, вот просто мне думается, что это можно как-то упростить.
Использование ThreadPool не приведёт к блокировке основного потока.
Думаю, лучше использовать System.Threading.Timer в качестве альтернативы вашему основному потоку. Всё же выглядит лучше, чем while (true).
Думаю, лучше использовать System.Threading.Timer в качестве альтернативы вашему основному потоку. Всё же выглядит лучше, чем while (true).
ThreadPool не блокирует, а вот постоянная выборка данных блокирует, именно она вынесена в отдельный поток.
Можно использовать Timer, но тогда нельзя будет использовать собственные алгоритмы задержки… А менять постоянно число таймера… какой смысл тогда в нем? У меня например есть задача проверки обработанных данных на удаленном Web сервисе, сначало через 1 минуту, затем через 5 минут, потом через 10 минут, потом снова через 1 минуту, потом еще через 30 секунд… Думаете с таймером будет удобнее?
Можно использовать Timer, но тогда нельзя будет использовать собственные алгоритмы задержки… А менять постоянно число таймера… какой смысл тогда в нем? У меня например есть задача проверки обработанных данных на удаленном Web сервисе, сначало через 1 минуту, затем через 5 минут, потом через 10 минут, потом снова через 1 минуту, потом еще через 30 секунд… Думаете с таймером будет удобнее?
Кстати для синхронизации доступа к List стоит использовать SyncRoot:
lock (ResultData.SyncRoot)
{
ResultData.Add(response);
}
Sign up to leave a comment.
Практика использования пространства System.Threading при написании многопоточных приложений в .NET.