У меня есть потоковое консольное приложение, которое работает нормально, но его архитектуру необходимо улучшить, и я хотел бы получить отзыв.
В настоящее время программа загружает список данных и сегментирует эти данные на разделы (один блок для каждого потока). Затем программа инициализирует новый поток, используя ThreadPool, и передает ему ОДИН сегмент сегментированных данных для работы.
Все работает хорошо ... кроме:
Некоторые потоки не работают ... из-за проблем с сетью или неисправимых исключений. Это ожидаемое поведение, а не ошибка.
Теперь мне нужен способ (в случае сбоя потока) восстановить сегмент данных этого потока и передать его другому рабочему потоку, чтобы он не потерял целостность. Я уверен, что есть способы сделать это, например, обмен данными между потоками и т. Д., Но я думаю, что есть лучший подход.
Вместо того, чтобы предварительно сегментировать данные и передавать их каждому потоку, я мог бы разделить ОДНУ статическую коллекцию этих данных между всеми потоками. Это более элегантно, но вводит новые проблемы с синхронизацией, о которых старому подходу не нужно было беспокоиться.
A.) Что вы думаете об этом подходе по сравнению со старым?
B.) Если этот подход хорош, как мне заблокировать доступ к общей статической коллекции.
Когда поток запускается, я могу заблокировать коллекцию и выдвинуть сегмент данных только для этого потока. Статическая коллекция теперь будет СНИЖЕНА на количество, потраченное на этот поток. После сбоя потока я мог перераспределить этот сегмент данных в общую коллекцию, снова заблокировав его и отправив данные обратно в коллекцию, чтобы другие потоки попытались обработать их.
Например: (непроверенный псевдокод)
void Process(object threadInfo)
{
lock(StaticCollection)
{
var segment = StaticCollection.Take(100);
StaticCollection.Remove(StaticCollection.Where(item => segment.Contains(item)))
}
foreach(var seg in segment)
{
// do something
}
// reallocate the thread's data on failure
if(unrecoverableErrorOccurred)
{
lock(StaticCollection)
{
StaticCollection.Add(segment);
}
}
}
Я на правильном пути с этим? Мне кажется, что один поток может удалять элементы одновременно, а другой поток перераспределяет элементы ... или делает блокировку для коллекции STATIC, что означает, что никакой другой поток не может получить доступ к этой коллекции вообще. Итак, Поток А.) получил блокировку в ПЕРВОЙ части метода, блокирует ли это все остальные потоки от выполнения части LAST метода до тех пор, пока Поток A не будет завершен?