Member 13245297 Ответов: 2

Как создать задачу или поток в C# и запустить его при необходимости


Привет,в моей программе я получаю некоторые значения каждую секунду с определенного ip-адреса. Я должен сделать некоторую операцию над этими значениями, которая занимает больше секунды. Если я потрачу секунду на эту операцию, я не смогу прочитать значения, сгенерированные в течение этой секунды, и я пропущу эти значения. Поэтому я планирую создать задачу в C# и вызывать ее всякий раз, когда я получаю значения и передаю им значения, чтобы она выполняла операцию, и я не пропустил бы никаких значений.
Я делал следующее
if(array_size)<500
{       
Task.Run(() => SendMessage(testarray));
}

Но я думаю, что это создает новую задачу каждый раз, когда я вызываю ее, и через несколько часов я получил исключение из памяти.
Не могли бы вы, ребята, предложить мне какой-нибудь эффективный способ решить эту проблему, чтобы я не столкнулся с ошибкой нехватки памяти. Кроме того, если это возможно, пожалуйста, поделитесь фрагментом решения.
Спасибо

Что я уже пробовал:

Я попытался запустить его ,и через несколько часов он рухнул бы с исключением из памяти

BillWoodruff

Есть ли возможность приостановить или задержать входящий поток данных ?

RickZeeland

На каком оборудовании вы запускаете свое приложение, какой процессор, объем памяти и т. д. ?

2 Ответов

Рейтинг:
1

OriginalGriff

Это не решит вашу проблему в долгосрочной перспективе: даже с потоковой системой, если ваша обработка занимает 1,1 секунды, и вы получаете новые данные каждые 1,0 секунды, вы будете длиться в 0,1 раза больше ядер, которые у вас есть в вашем процессоре секунд в лучшем случае прежде чем вы снова потеряете данные.

Потоковая обработка не может решить эту проблему, на самом деле она может усугубить проблему, потому что каждый поток добавляет дополнительные накладные расходы с точки зрения памяти и времени обработки, что усложняет вашу задачу.

Вам нужно очень внимательно посмотреть на работу обработки, которую вы выполняете, и либо повысить ее эффективность, либо заменить ее более эффективным алгоритмом, чтобы ваша обработка заняла 0,9 секунды, а не пытаться "разгрузить" проблему на потоки.

Извините, но мы не можем сделать это для вас.


Member 13245297

Привет. Спасибо, что указал на эту ошибку. Что делать, если я поддерживаю очередь и ставлю ее в очередь с прочитанным сообщением, и у меня есть задача, которая будет периодически удалять содержимое из очереди и обрабатывать его? Это будет гарантировать, что я не пропущу никаких данных, верно? Спасибо

OriginalGriff

Нет, у тебя все равно будет та же проблема.
Если вы не можете удалить материал из очереди быстрее, чем он поступает, то в конечном итоге у вас закончится память - у вас всегда будет конечное число ядер для запуска потоков (и каждый поток нуждается в свободном ядре для выполнения).
Вот что показывает ваш текущий код: ваша очередь заполняется быстрее, чем вы снимаете вещи.

Либо вам нужно ускорить обработку каждого пакета, либо уменьшить частоту, с которой они поступают.

Рейтинг:
0

RickZeeland

Вы можете использовать taskname.IsCompleted, а затем распорядитесь заданием, см.: Как это сделать: дождитесь завершения одной или нескольких задач[^]
Пример:

Task checkProcesses = Task.Factory.StartNew(this.CheckProcesses);
//... e.g. a loop ...
While (True)
{
  if (checkProcesses.IsCompleted)
  {
	checkProcesses.Dispose();
	checkProcesses = Task.Factory.StartNew(this.CheckProcesses);
  }
}

private void CheckProcesses()
{
}


BillWoodruff

Это звучит разумно только в том случае, если ОП может приостановить/задержать входящий поток данных ... имхо, описание операции предполагает, что это невозможно.

RickZeeland

Он мог использовать несколько задач или массив задач в цикле.
Но ключевая проблема мне кажется в том, что его задачи не расположены должным образом, обычно dispose не должен быть нужен для задач, но в его случае это кажется необходимым ...