Здравствуйте! Есть 10 List, в которые поступают новые данные и которые надо обрабатывать. Есть входящие данные в количестве >1000/сек, которые поступаю c рандомной частотой. Придумал 2 способа их обрабатывать, подскажите минусы/плюсы или 3ий вариант.
1ый способ
class MyClass
{
//list который хранит все string
List<List<string>> ListString = new List<List<string>>();
//переменная для блокировки доступа
List<Object> ListLocker = new List<Object>();
//List c отдельным thread для каждого List
List<Thread> ListThread;
//конструктор
public MyClass()
{
//инициализируем List
for(int i = 0; i < 10; i++)
{
ListLocker.Add(new Object());
ListThread.Add(new Thread(InitThread));
}
}
//функция для инициализации Thread
private void InitThread()
{
}
//псевдофункция определяет принадлежность String к одному из List
private int SearchIndex(string String)
{
for(int i = 0; i < ListString.Count; i++)
{
if(String.Contains(i.ToString()))
{
return i;
}
}
return -1;
}
//фунция принимает обновления из вне
public void OnUpdate(string String)
{
//получаем индекс
int i = SearchIndex(String);
if(i > -1)
{
//добавляем входящие данные в свой List
lock(ListLocker[i])
{
ListString[i].Add(String);
}
if(!ListThread[i].IsAlive)
{
ListThread[i] = new Thread(new ParameterizedThreadStart(ReadList));
ListThread[i].Start(i);
}
}
}
//функция обрабатывает данные
private void ReadList(object incomeIndex)
{
//convert
int index = (int)incomeIndex;
int ListLenght = 0;
lock(ListLocker[index])
{
//получаем кол-во строк
ListLenght = ListString[index].Count;
}
for(int i = 0; i < ListLenght; i++)
{
//обрабатываем 0 строку...
WorkWithString(ListString[index][0]);
lock(ListLocker[index])
{
//удаляем 0 строку
ListString[index].RemoveAt(0);
}
//проверяем появились еще данные в ListString, если да, не отпускаем поток, анализируем все новые строки
if(i == ListLenght)
{
lock(ListLocker[index])
{
//получаем новое кол-во
ListLenght = ListString[index].Count;
if(ListLenght > 0)
{
//запускаем цикл for снова
i = -1;
}
}
}
}
}
private void WorkWithString(string String)
{
//work, work
}
}
В этом способе минус в том, что очень много ресурсов уходит на создание потока.
ListThread[i].Start(i);
2 способ основан на бесконечном цикле, но зато с одним Thread
class MyClass2
{
//list который хранит все string
List<List<string>> ListString = new List<List<string>>();
//переменная для блокировки доступа
List<Object> ListLocker = new List<Object>();
//List c отдельным thread для каждого List
Thread Thread;
//конструктор
public MyClass2()
{
//инициализируем List
for(int i = 0; i < 10; i++)
{
ListLocker.Add(new Object());
Thread = new Thread(new ThreadStart(InitThread));
}
}
//функция для инициализации Thread
private void InitThread()
{
}
//псевдофункция определяет принадлежность String к одному из List
private int SearchIndex(string String)
{
for(int i = 0; i < ListString.Count; i++)
{
if(String.Contains(i.ToString()))
{
return i;
}
}
return -1;
}
//фунция принимает обновления из вне
public void OnUpdate(string String)
{
//получаем индекс
int i = SearchIndex(String);
if(i > -1)
{
//добавялем входящие данные в свой List
lock(ListLocker[i])
{
ListString[i].Add(String);
}
if(!Thread.IsAlive)
{
Thread = new Thread(new ThreadStart(ReadList));
Thread.Start();
}
}
}
private void ReadList()
{
//прокручиваем все ListString
for(int index = 0; index < ListString.Count; index++)
{
lock(ListLocker)
{
if(ListString[index].Count > 0)
{
//прокручиваем все String
for(int i = 0; i < ListString[index].Count; i++)
{
//обрабатываем 0 строку...
WorkWithString(ListString[index][0]);
//удаляем 0 строку
ListString[index].RemoveAt(0);
}
}
}
//не отпускаем поток, зацикливая его бесконечно
if(index == ListString.Count)
{
index = -1;
Thread.Sleep(0);
}
}
}
private void WorkWithString(string String)
{
//work, work
}
}
Большой минус второго способа, в том, что во время работы функции ReadList(), идет блокировка и новые данные будут висеть в очереди на запись.
Так же есть еще один вопрос, касательно запуска Thread:
Thread = new Thread(new ThreadStart(InitThread));
Как сделать это правильно? Если так не делать при запуске приложения ругается, что переменная не инициализирована, а инициализировать без указания функции, невозможно. Спасибо!
CompleteAdding, если данные ещё будут приходить. Вызывайте лишь тогда, когда больше данных точно не будет. – VladD Aug 12 '16 at 15:33