C# 使用多线程时,程序会变得慢得多

C# 使用多线程时,程序会变得慢得多,c#,multithreading,C#,Multithreading,我的任务是比较数据库中两个表中的数据以获得相似性, 例如,如果每个表有5条记录,那么我需要将表A中的每条记录与表B中的所有记录进行比较,以获得相似性。 在我使用单线程之前,如果每个表有500条记录,它使用4分钟,现在我使用4个线程,它使用半小时! 这是我的想法,我将第一个表分成4个表,每个表存储部分数据,然后使用线程池中的4个线程开始比较, 这是代码,p1,p2是表格 Deduplication d = new Deduplication(pr2, threshold); Func<Li

我的任务是比较数据库中两个表中的数据以获得相似性, 例如,如果每个表有5条记录,那么我需要将表A中的每条记录与表B中的所有记录进行比较,以获得相似性。 在我使用单线程之前,如果每个表有500条记录,它使用4分钟,现在我使用4个线程,它使用半小时! 这是我的想法,我将第一个表分成4个表,每个表存储部分数据,然后使用线程池中的4个线程开始比较, 这是代码,p1,p2是表格

Deduplication d = new Deduplication(pr2, threshold);

Func<List<ParentRecord>, List<ParentRecord>> method = d.Find;

for (int i = 0; i < 4; i++)
{
    IEnumerable<ParentRecord> temp = pr1.Skip(i*part).Take(part);
    method.BeginInvoke(temp.ToList(), CallBackMethod, method);
}

private void CallBackMethod(IAsyncResult result)
{
    countThread++;

    var target = (Func<List<ParentRecord>, List<ParentRecord>>)result.AsyncState;
    List<ParentRecord> p=target.EndInvoke(result);
    lock (_locker)
    {
        records.AddRange(p);
    }
    if (countThread > 3)
    {
        this.BeginInvoke(new PopulateDelegate(PopulateGridView), new object[] { records });
    }
}

private void PopulateGridView(List<ParentRecord> p)
{ 
    dataGridViewParent.DataSource = p;
    dataGridViewDuplication.DataSource = null;
}
很抱歉,我是多线程新手,所以这个想法听起来可能有点愚蠢,如果您能解释一下,我将不胜感激,谢谢

更新

public List<ParentRecord> Find()
    {
        List<ParentRecord> result = new List<ParentRecord>();

        foreach (ParentRecord p1 in DataSource1)
        {
   List<DuplicateRecord> addedDuplicateRecords = new List<DuplicateRecord>();
            int num = 0;
            foreach (ParentRecord p2 in DataSource2)
            {

                //Check if these two rows have the same primary keys
                if (p1.PrimaryKey != p2.PrimaryKey)
                {
                    float similarity = 0F;
                    //Check if these two rows are the simply the same
                if (p1.CompareRow.ToUpper() == p2.CompareRow.ToUpper()) similarity = 1;
                    else similarity = GetSimilarity(p1.CompareRow, p2.CompareRow);
                    if (similarity >= threshold)
                    {
                        DuplicateRecord duplicateRecord = new DuplicateRecord();
                        duplicateRecord.PrimaryKey = p2.PrimaryKey;
                        duplicateRecord.CompareToRow = p2.CompareRow;
                        duplicateRecord.Similarity = similarity;
                        addedDuplicateRecords.Add(duplicateRecord);
                        num++;
                    }
                }
            }
            //Check if there are any reocrds meet the threadhold
            if (num > 0)
            {
                ParentRecord parentRecord = new ParentRecord();
                parentRecord.PrimaryKey = p1.PrimaryKey;
                parentRecord.CompareRow = p1.CompareRow;
                parentRecord.duplicateRecordList = addedDuplicateRecords;
                result.Add(parentRecord);
            } 
        }
        return result; 
    }

    private float GetSimilarity(object obj1, object obj2)
    {
        float similarity = 1;


        MatchsMaker match = new MatchsMaker(obj1.ToString(), obj2.ToString());

        similarity = match.Score;


        return similarity;
    }

}

很难理解这是怎么回事。
我会尝试解决完全不同的问题,可能是通过使用精心编制的查询或将所有数据读入内存,而不是尝试从多个线程逐步执行查询。

我猜您可能是在业务层死锁和/或在数据库中获取表级锁

在我的脑海里,有很多选择:

并排读取两个数据读取器 数据库游标这可能是合法使用 基于一系列内部联接比较记录计数 假设您正在使用SQL Server的CTE
如果您运行的性能测试只有500条记录,我无法想象这些方法中的任何一条都需要几分钟以上。

您能发布d.Find的代码吗?这就是问题所在。但是所有的数据都不在数据库中了,我将它们复制到不同的数组列表中,您的猜测还会是这样吗?