Мне поручено написать систему для обработки файлов результатов, созданных другим процессом (с которыми я не контролирую), и пытаюсь изменить мой код, чтобы использовать Parallel.Foreach. Код работает отлично, когда вы вызываете foreach, но у меня есть некоторые проблемы с безопасностью потоков при использовании параллельной версии. Базовый вопрос, на который мне нужно ответить, - «Я так делаю, чтобы гарантировать безопасность потока?» или это приведет к тому, что все пойдет ко мне.Есть частные свойства класса, называемого в Parallel.Foreach body Thread Safe?
Я попытался удостовериться, что все вызовы являются экземплярами и удалили все статические все, кроме начального статического void Main. По моему мнению, это будет делать многое для обеспечения безопасности потоков.
У меня в основном следующие, отредактированный для краткости
static void Main(string[] args)
{
MyProcess process = new MyProcess();
process.DoThings();
}
А потом в самом процессе, чтобы сделать вещи у меня есть
public class MyProcess
{
public void DoThings()
{
//Get some list of things
List<Thing> things = getThings();
Parallel.Foreach(things, item => {
//based on some criteria, take actions from MyActionClass
MyActionClass myAct = new MyActionClass(item);
string tempstring = myAct.DoOneThing();
if(somecondition)
{
MyAct.DoOtherThing();
}
...other similar calls to myAct below here
};
}
}
и снова в MyActionClass у меня есть что-то вроде следующего:
public class MyActionClass
{
private Thing _thing;
public MyActionClass(Thing item)
{
_thing = item;
}
public string DoOneThing()
{
return _thing.GetSubThings().FirstOrDefault();
}
public void DoOtherThing()
{
_thing.property1 = "Somenewvalue";
}
}
Если я могу объяснить это лучше, я попробую, но я думаю, что это основы моих потребностей
EDIT: Что-то еще я только что заметил. Если я изменяю значение свойства item Я работаю в то время как внутри Parallel.Foreach
(в этом случае строковое значение, которое записывается в базу данных внутри цикла), будет иметь какое-либо влияние на остальную часть итерации цикла или только тот, на котором я нахожусь? Было бы лучше создать новый экземпляр Thing внутри цикла для хранения элемента, с которым я работаю в этом случае?
Я попытался пройти весь код и убедиться, что нет вызовов статическим методам. Я пошел дальше и заменил все статические методы на экземпляры и старался не вызывать ничего из созданного вне 'Parallel.Foreach' изнутри цикла (за исключением фактического ** элемента **, с которым я выполняю итерацию) , Я просто очень новичок в потоковом в целом, и у меня есть немного времени, обертывающего мою голову вокруг всего этого. Как показано выше, в живом коде я ввел 'Parallel.Foreach' почти сразу после ввода метода и делал все вызовы из него в экземпляры. – Rocky
Редактировать: добавлено в базовый вопрос – Rocky
Я думаю, что неизменяемость может работать здесь, так как обычно мне не нужно менять какой-либо элемент в списке, кроме одной строки, и, как сказано, я думаю, что могу просто создать новый экземпляр класса и передать ** элемент ** в это для этого.В конце концов, я просто читаю строки в файле и предпринимаю некоторые действия на их основе. Я займусь этим. – Rocky