Я новичок в многопоточном программировании, и у меня есть несколько вопросов по этому поводу.Я разрабатываю запланированное задание, загружающее файл .xls, который требует проверки каждой строки с данными и после открытия запроса в приложении, и реализую многопоточность для обработки каждой строки, стремясь добиться некоторой производительности.
В моей работе у меня есть что-то вроде этого примера:
public class Job
{
private readonly IUserBLO _userBLO;
private readonly IRequestBLO _requestBLO;
private readonly object _lockerSheet;
public Job()
{
_userBLO = Factory.CreateInstance("UserBLO");
_requestBLO = Factory.CreateInstance("RequestBLO");
_lockerSheet = new object();
}
public void ProcessJob(BinaryWriter binary)
{
using (ExcelPackage package = new ExcelPackage(binary))
{
var sheet = package.Workbook.Worksheet[1];
var rows = Enumerable.Range(sheet.Dimensions.Start.Row, sheet.Dimensions.End.Row);
Parallel.ForEach(rows, row =>
{
try
{
var excelData = GetExcelData(sheet, row);
ValidadeData(excelData);
_requestBLO.OpenRequestByExcelData(excelData);
}
catch (Exception ex)
{
LogError(ex);
}
});
}
}
public List<string> GetExcelData(ExcelWorksheet sheet, int row)
{
var excelData = new List<string>();
for (int i = sheet.Dimensions.Start.Column; i <= sheet.Dimensions.End.Column; i++)
{
lock (_lockerSheet)
{
var cellValue = sheet.Cells[row, i].Text;
}
excelData.Add(cellValue);
}
return excelData;
}
public void ValidadeData(List<string> excelData)
{
var userLogin = excelData.First();
var user = _userBLO.FindByLogin(userLogin);
if (user == null)
throw new Exception("User not found!");
}
}
Когда я кодировал, у меня были некоторые проблемы, которые, когда я пытался получить значение из листа в случайной позиции, иногда возвращалось пустымхотя эта позиция имела значение.После некоторого поиска в Google, я попытался использовать шкафчик в тот момент, когда я получал значение из листа, и, по-видимому, работал!
lock (_lockerSheet)
{
var cellValue = sheet.Cells[row, i].Text;
}
После этой ситуации у меня возникло несколько вопросов:
- Каждая «локальная» переменная, которая будет параллельно использоваться в задачах, должна быть заблокирована, даже если эта переменная доступна только для чтения.Я прав?
- Если приведенный выше вопрос верен, нужно ли мне использовать блокиратор в переменных _userBLO и _requestBLO, которые являются интерфейсами, связанными с некоторыми конкретными методами?
- Если первыйвопрос ложный, мне просто нужно использовать шкафчик, если переменная получит какое-то значение в задаче?Когда мне действительно нужно использовать шкафчик?
PS: Извините за мой плохой английский!Бразильский здесь!:)