如何使用ThreadPool并行化数据库查询?

时间:2010-07-19 05:14:58

标签: c# stored-procedures threadpool

我正在修改其他人的代码,其中需要很长时间才能返回以下代码中的完整数据集:

DataTable dt = someLib.GetDataTable("EXEC [dbo].[CMS_Content_GetAllContents]");

// Copy the DataTable data to list.
foreach (DataRow dr in dt.Rows)
{
    ContentInfo aContentDetail = new ContentInfo(
            (int)dr["ID"],
            (string)dr["ContentName"],
            getCategories((int)dr["ID"]),
            null,
            (string)dr["Publisher"],
            (string)dr["Price"],
            false);

    contentInfoList.Add(aContentDetail); ;
}

private string getCategories(int ContentID)
{
    String categories = String.Empty;
    String query = String.Format("EXEC [dbo].[CMS_Content_GetContentCategories] @ID = {0}", ContentID);

    DataTable dt = clsGlobal.GetDataTable(query);

    foreach (DataRow dr in dt.Rows)
    {
        categories = String.Concat((string)dr["ShortDescription"] + ", ");                
    }

    if (categories.EndsWith(", "))
        categories = categories.TrimEnd(new char[] { ',', ' ' });

    return categories;
}

由于DataTable dt有超过1,000行,我无法从存储过程级别处理它,这是可悲的!

我只是想知道我是否可以将调用getCategories(int)捆绑到Threadpool.QueueUserWorkItem(),以便它可以并行,但不知道如何将字符串返回给调用者?

或者,使用Threadpool是一个坏主意,因为我听说Threadpool的工作线程不是为长时间运行的查询设计的,例如DB调用,因为IOCompletion端口线程可能无法及时返回,因此工作人员可能会被阻止,因为那个?

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:1)

我担心在这种情况下线程不是解决方案(在线程池上或线程池外)。修复1000个调用数据库是。您可以针对少数用户优化响应速度,但响应时间仍然非常难以忍受,并且您的应用程序将在极低负载下瘫痪。

我不知道你对数据库有多少控制权,所以这里有一些跨越几层的想法:

  1. 使用内容拉出类别。您可以创建一个func来对其进行字符串分隔,也可以使用在一次调用中返回多个数据集的proc。
  2. 一次加载所有类别,并将数据放在内存中
  3. 更改您的UI,以便您不会同时使用1000个CMS项目。寻呼或其他什么。
  4. 祝你好运。

答案 1 :(得分:0)

尽管如此,这个问题已经得到了回答。但这只是可能有所帮助。

您可以在工作线程中“移动”代码并让它运行。您还可以创建添加事件,一旦线程完成工作,它就会让您知道。通过这种方式,您可以继续(或将进度条移动到最后,如果您有任何?)与其余的工作。

  1. Here就是你如何处理线程。
  2. 迄今为止what I love
  3. 作为旁注,我相信这可以在SP中完成(如果你可以共享查询);因此我会创建一个获取内容详细信息的SP,对于每个ContentDetailID,我会准备一个逗号分隔的类别列表,然后返回我的结果。

    所以,你的电话就是:

    DataTable dt = someLib.GetDataTable("EXEC [dbo].[CMS_Content_GetAllContents_Ex]");//Note the _EX in the sp name (0: