性能问题执行存储过程列表

时间:2015-06-22 13:58:59

标签: c# multithreading performance loops

我在启动Windows服务时遇到了一些性能问题,第一轮我的lstSps很长(大约130个存储过程)。无论如何都要加快速度(除了加快存储过程的速度)?

当foreach结束并进入第二轮时,它会更快,因为在TimeToRun()上没有多少返回true。但是,我关注的是第一次,当有更多的存储过程要运行时。

我有关于创建一个数组和一个for循环,因为我读得更快,但我相信问题是因为这些过程需要很长时间。我可以用更好的方式构建它吗?也许使用多个线程(每个执行一个)或类似的东西?

非常感谢一些提示:)

编辑:只是为了澄清一下,它的方法HasResult()正在执行SP:s并且看起来需要时间......

lock (lstSpsToSend)
{
    lock (lstSps)
    {
        foreach (var sp in lstSps.Where(sp => sp .TimeToRun()).Where(sp => sp.HasResult()))
        {
            lstSpsToSend.Add(sp);
        }
    }
}

while (lstSpsToSend.Count > 0)
{
    //Take the first watchdog in list and then remove it
    Sp sp;
    lock (lstSpsToSend)
    {
        sp = lstSpsToSend[0];
        lstSpsToSend.RemoveAt(0);
    }

    try
    {
        //Send the results
    }
    catch (Exception e)
    {
        Thread.Sleep(30000);
    }
}

2 个答案:

答案 0 :(得分:1)

我会做的是这样的事情:

int openThread = 0;
ConcurrentQueue<Type> queue = new ConcurrentQueue<Type>();
foreach (var sp in lstSps)
{
    Thread worker = new Thread(() =>
        {
            Interlocked.Increment(ref openThread);
            if(sp.TimeToRun() && sp.HasResult)
            {
                queue.add(sp);
            }
            Interlocked.Decrement(ref openThread);
        }) {Priority = ThreadPriority.AboveNormal, IsBackground = false};
        worker.Start();
}
// Wait for all thread to be finnished
while(openThread > 0)
{
    Thread.Sleep(500);
}

// And here move sp from queue to lstSpsToSend

while (lstSpsToSend.Count > 0)
{
    //Take the first watchdog in list and then remove it
    Sp sp;
    lock (lstSpsToSend)
    {
        sp = lstSpsToSend[0];
        lstSpsToSend.RemoveAt(0);
    }

    try
    {
        //Send the results
    }
    catch (Exception e)
    {
        Thread.Sleep(30000);
    }
}

答案 1 :(得分:0)

最好的方法很大程度上依赖于这些存储过程实际执行的操作,如果它们返回相同类型的结果集,或者没有结果,那么将它们一次性发送到SQL服务器肯定是有益的而不是一次一个。

原因是网络延迟,如果您的SQL服务器位于您通过WAN访问的某个数据中心,您的延迟可能会超过200毫秒。因此,如果你按顺序调用130个存储过程,那么“cost”将是200ms X 130.这是26秒,只是通过网络连接来回运行而不是实际执行proc中的逻辑。

如果您可以将所有程序合并为一个电话,则只需支付200毫秒的费用。

在多个并发线程上执行它们也是一种合理的方法,但与以前一样,它取决于您的程序正在做什么并返回给您。

在列表上使用数组并不能真正提高性能。

希望这有帮助,祝你好运!