C# 并行任务&;锁定局部变量

C# 并行任务&;锁定局部变量,c#,multithreading,parallel-processing,locking,task,C#,Multithreading,Parallel Processing,Locking,Task,我是多线程编程新手,对此我有一些疑问。我正在开发一个调度作业,加载一个.xls,在应用程序中打开一个请求后,每一行都需要验证数据,并且我正在实现多线程来处理每一行,以获得一些性能 在我的工作中,我有这样的例子: public class Job { private readonly IUserBLO _userBLO; private readonly IRequestBLO _requestBLO; private readonly object _lockerShee

我是多线程编程新手,对此我有一些疑问。我正在开发一个调度作业,加载一个.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!");
    }
}
在这种情况下,我有一些问题:

  • 对于每个将在任务中并行使用的“局部”变量,即使该变量是只读的,也需要锁定。我说的对吗
  • 如果上面的问题是真的,我是否需要在_userBLO和_requestBLO变量中使用一个锁,这是包含一些特定方法的接口
  • 如果第一个问题为false,那么如果变量在任务中接收到一些值,我是否只需要使用一个锁?我什么时候真的需要使用储物柜

  • PS:对不起,我的英语不好!这里是巴西人!:)

    我想我的答案在评论中会更有意义,因为亨克总结得更好,但是。它将帮助您理解为什么线程安全很重要。等等,您是否试图使用Excel对象,好像它们支持自由线程编组?是吗?我原以为Excel是公寓,不是出租的,也不是免费的,但自从我上次尝试针对Excel编写多线程代码以来,已经有十五年了。我可能记错了。如果您试图以并行方式租用线程,首先,这将非常慢,破坏您的并行性收益,其次,Excel将崩溃。你能更详细地解释你的线程模型吗?@EricLippert-ExcelPackage是开放式XML,我认为这里没有运行Excel实例。@HenkHolterman:谢谢你的提示。那么就不用担心了——假设开放XML是自由线程的,那么封送器就没有问题了。然而,您仍将破坏并行性。如果您需要在并行步骤中设置一个锁,那么首先它可能是不可并行的。它是一个承诺“服务器上的电子表格OOXML”的旧包。我刚刚了解到FireFox已经)
    lock (_lockerSheet)
    {
        var cellValue = sheet.Cells[row, i].Text;
    }