Я хотел знать, как повторно использовать поток. У меня есть соединение через веб-сокет, которое постоянно отправляет сообщения, которые требуют выполнения некоторых вычислений. Я хочу добавить это вычисление в поток, но не хочу каждый раз создавать новый поток. Как я могу сделать так, чтобы поток использовался повторно?
client.MsgRecieved.Subscribe(info =>
{
Thread t = new Thread(() => Do_work(info));
};
Есть ли способ создать тему, назвать ее, а затем просто добавить Do_work() в эту тему?
Редактировать:
Я получаю несколько сообщений из веб-сокета в секунду. Я предпочитаю, чтобы они ждали в одной очереди, а не запускались в новом потоке.
Я получаю несколько сообщений из веб-сокета в секунду. Я предпочитаю, чтобы они ждали в одной очереди, а не запускались в новом потоке.
Затем вы можете использовать для этого класс ConcurrentQueue (поточно-безопасная версия Queue). Пусть ваш один поток постоянно зацикливается и пытается вытащить материал из очереди, в то время как другой поток добавляет к нему материал по мере необходимости.
semaphoreslimТо, что вы спрашиваете, подразумевает, что Do_work будет сериализован. Учитывали ли вы, что если обработчик Subscribe вызывается чаще, чем средняя продолжительность Do_work, сообщения info будут накапливаться в постоянно увеличивающемся буфере?





Самый простой узор просто
client.MsgRecieved.Subscribe(async info =>{
await Task.Run(Do_work(info));
});
Который ставит в очередь метод для запуска во встроенном пуле потоков.
Если вы хотите поставить сообщения в очередь для запуска в одном фоновом потоке, вы можете использовать BlockingCollection, например:
var workQueue = new System.Collections.Concurrent.BlockingCollection<Object>();
var workThread = new System.Threading.Thread(() =>
{
foreach (var work in workQueue.GetConsumingEnumerable())
{
Do_Work(work);
}
});
workThread.Start();
затем
client.MsgRecieved.Subscribe(info => {
workQueue.Add(info);
};
Имейте в виду, что задачи не связаны напрямую с потоками (несколько задач могут выполняться в одном потоке). Это также может привести к ошибке, если задача выполняется несколько часов, а вы не используете флаг TaskCreationOptions.LongRunning.
Вместо client.MsgRecieved.Subscribe(info => { Task.Run( я бы предпочел client.MsgRecieved.Subscribe(async info => { await Task.Run(, чтобы любые ошибки, которые могут произойти, выявлялись (как необработанные исключения).
Вы не можете повторно использовать поток. Рассмотрите возможность использования ThreadPool.