C#这些静态方法线程安全吗?

时间:2017-10-24 11:16:29

标签: c# multithreading static static-methods

我遇到这种情况:

private static EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>();

private List<Set> SplitBySetId(List<Step> stepList)
{
    List<Set> outputSetList = new List<Set>();

    using (entityBuilderCore)
    {
        stepList.ForEach(step =>
        {
            // For each step, I find the corrispectives set's ids (one or more).
            // Then, I create the Set
            List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);

            // Create Sets and adding to the output list
            setIdList.ToList().ForEach(id =>
            {
                if (!outputSetList.Any(set => set.Id == id))
                    outputSetList.Add((Set)entityBuilderCore.GetEntity(typeof(Set), id));
            });
        });
    }

    return outputSetList;
}

但我可以在很多Set中细分很多步骤......所以我想以这种方式进行并行化(看起来是添加部分):

private List<Set> SplitBySetId(List<Step> stepList)
{
    List<Set> outputSetList = new List<Set>();

    using (entityBuilderCore)
    {
        stepList.ForEach(step =>
        {
            // For each step, I find the corrispectives set's ids (one or more).
            // Then, I create the Set
            List<int> setIdList = entityBuilderCore.GetSetIdByStep(step);

            // Create Sets and adding to the output list
            var tempList = setIdList.Distinct()
                .AsParallel()
                .Where(id => !outputSetList.Any(set => set.Id == id))
                .Select(setId => (Set)entityBuilderCore.GetEntity(typeof(Set), setId));

            outputSetList.AddRange(tempList);
        });
    }
    return outputSetList;
}

但我不确定entityBuilderCore的线程安全性。核心是:

class EntityBuilderCore : CoreBase
{
    private static EntityRepository Repository;

    protected override string _connectionString
    {
        get { return ConfigurationService.Instance.GetValue("connessione_database_sinistriweb"); }
    }

    private EntityBuilderCore()
    {
        Repository = new EntityRepository() { ConnectionString = _connectionString };
    }

    public BaseEntity GetEntity(Type entityType, int id)
    {
        return EntityBuilder.BuildEntity(entityType, Repository.GetEntity(entityType, id));
    }

    // ...

    public List<int> GetSetIdByStep(Step step)
    {
        return Repository.GetSetIdByStep(step);
    }

}



class EntityRepository : RepositoryBase
{
    Dictionary<Type, string> tableDictionary = new Dictionary<Type, string>();

    public EntityRepository()
    {
        tableDictionary.Add(typeof(SQL), "PROCESSI.DBO.GFE_SQL");
        tableDictionary.Add(typeof(Step), "PROCESSI.DBO.GFE_STEP");
        tableDictionary.Add(typeof(StepSet), "PROCESSI.DBO.GFE_SET");
    }

    public DataRow GetEntity(Type systemType, int id)
    {
        string entityTable;
        tableDictionary.TryGetValue(systemType, out entityTable);

        using (SqlConnection connection = new SqlConnection(ConnectionString))
        using (SqlCommand command = new SqlCommand(string.Format("SELECT * FROM {0} WHERE ID = @ID", entityTable), connection))
        {
            connection.Open();
            command.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = id;
            using (SqlDataReader dr = command.ExecuteReader())
            {
                if (dr.Read())
                {
                    DataTable entityDataTable = new DataTable();
                    SqlDataAdapter dataAdapter = new SqlDataAdapter();
                    dataAdapter.SelectCommand = command;
                    connection.Close();
                    dataAdapter.Fill(entityDataTable);
                    return entityDataTable.Rows[0];
                }
            }
        }

        return null;
    }

    public List<int> GetSetIdByStep(Step step)
    {
        // bla bla
    }

    // ...

}

我更喜欢在EntityBuilder类中只使用一个entityBuilderCore。我更喜欢不每次实例化entityBuilderCore,我认为是没用的。但我担心不是线程安全,因为SplitBySetId方法同时被许多任务使用

class EntityBuilder
{
    public static BaseEntity BuildEntity(Type entityType, DataRow dr)
    {
        if (entityType == typeof(SQL))
            return BuildSQL(dr);

        if (entityType == typeof(Step))
            return BuildStep(dr);

        if (entityType == typeof(Set))
            return BuildSet(dr);

        return null;
    }


    //...

    private static Step BuildStep(DataRow dr)
    {
        using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
        {
            Step s = new Step()
            {
                Id = Convert.ToInt16(dr["ID"]),
                //... bla bla
            };
            return s;
        }
    }

    private static Set BuildSet(DataRow dr)
    {
        using (EntityBuilderCore entityBuilderCore = ServiceFactory.Create<EntityBuilderCore>())
        {
            Set s = new Set()
            {
                Id = Convert.ToInt16(dr["ID"]),
                //...
            };

            return s;
        }
    }
}

0 个答案:

没有答案