DataTable в общий список, используя задачу, чтобы сделать это быстрее - PullRequest
0 голосов
/ 19 февраля 2019

Начали ускорять преобразование из dataTable в List, поскольку у меня есть 20K-запись в datatable, и ее обычное преобразование занимает от 5 до 7 минут.Так что я подумал, чтобы сделать это быстрее, используя Parallel.ForEach или Task, но по-прежнему безрезультатно - любые предложения, пожалуйста.Му код, как показано ниже:

 public static List<T> FillFromStoredProc<T>(string storedproc, SqlParameter[] prms) where T : IReadOnlyDatabaseObject, new()
    {
      DataTable dt = DatabaseHelper.runStoredProc(Configuration.Instance.ConnectionString, storedproc, prms);

       ConcurrentBag<T> bag = new ConcurrentBag<T>();
        IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();

        Parallel.ForEach(dt.AsEnumerable(), new ParallelOptions { MaxDegreeOfParallelism = 10 }, Drow => {

            bag.Add(GetFromDataRow<T>(Drow, properties));
        });

       return bag.ToList();
    }
 public static T GetFromDataRow<T>(DataRow dr, IList<PropertyInfo> properties) where T : IReadOnlyDatabaseObject, new()
    {
        T ret = new T();
        ret.LoadFromDataRowAsync(dr, properties);
        return ret;
    }
 public virtual void LoadFromDataRowAsync(DataRow dr, IList<PropertyInfo> properties)
    {
        Parallel.ForEach(properties, new ParallelOptions { MaxDegreeOfParallelism = 10 }, prop =>
        {
            try
            {
                if (dr.Table.Columns.Contains(prop.Name))
                {
                    if (prop.PropertyType.BaseType.Name == "Enum")
                    {
                        prop.SetValue(this, Enum.Parse(prop.PropertyType, dr[prop.Name].ToString()));
                    }
                    else
                    {
                        var val = DatabaseHelper.ConvertFromDBVal(prop.GetType(), dr[prop.Name]);

                        if (prop.PropertyType == typeof(DateTime))
                        {
                            // Convert back from DB value

                            if ((DateTime)(val) == SqlDateTime.MinValue)
                            {
                                val = DateTime.MinValue;
                            }
                        }

                        prop.SetValue(this, val);
                    }
                }
            }
            catch
            {
            }
        });

    }

Пожалуйста, помогите мне сделать это быстрее.Спасибо

1 Ответ

0 голосов
/ 21 февраля 2019

Вложенный параллелизм бесполезен и его следует избегать, потому что обычно он только ухудшает общую производительность.

Ваше узкое место - это отражение - оно медленное.Вы должны придумать альтернативу.Например, вы можете создать базовый класс для ваших универсальных типов и использовать виртуальный метод, который отображает имя свойства на фактическое свойство.Это звучит как довольно грубая и грязная работа, но она будет более эффективной.

...