【问题标题】:Handle Queue faster更快地处理队列
【发布时间】:2012-11-29 07:59:02
【问题描述】:

我有一个队列,它接收数据超时。 我使用多线程出列并保存到数据库。 我创建了一个线程数组来完成这项工作。

for (int i = 0; i < thr.Length; i++)
{
    thr[i] = new Thread(new ThreadStart(SaveData));
    thr[i].Start();
}

保存数据

注意:eQ 和 eiQ 是 2 个全局队列。我用 while 来保持线程活着。

public void SaveData()
{

    var imgDAO = new imageDAO ();
    string exception = "";
    try
    {
        while (eQ.Count > 0 && eiQ.Count > 0)
        {
            var newRecord = eQ.Dequeue();
            var newRecordImage = eiQ.Dequeue();                        

            imageDAO.SaveEvent(newEvent, newEventImage);

            var storepath = Properties.Settings.Default.StorePath;
            save.WriteFile(storepath, newEvent, newEventImage);
        }
    }
    catch (Exception e)
    {                
        Global._logger.Info(e.Message + e.Source);
    }
}

它确实创建了多线程,但是当我调试时,只有 1 个线程活着,其余的都死了。 我不知道为什么?有人知道吗?谢了

【问题讨论】:

  • 可能是SaveData 运行速度比新线程启动快?
  • 你能展示你的线程函数吗?您使用的是 SQLServer 还是其他数据库?
  • 除此之外,您似乎遇到了竞争条件...
  • 我新建了一个线程数组[4],所有它们的开始都是空的,所以 thr[i] = new Thread(new ThreadStart(SaveData)); thr[i].Start();创建线程
  • 我怀疑这不是正确的检查方法,您可以使用日志来知道哪个线程正在调用您的方法。您可以参考这个答案来调试多线程应用程序:stackoverflow.com/questions/4329528/…

标签: c# arrays multithreading queue


【解决方案1】:

您在该线程函数中使用WriteFile

这是否可能,您尝试写入可能被另一个线程锁定的文件(相同的文件名或其他东西)?

还有一件事——通过多个线程在磁盘上保存数据——我不喜欢它。

我认为您应该创建一些缓冲区而不是许多线程,并每隔几条记录/条目写入一次。

【讨论】:

  • 或者将要写入的事件传递到另一个队列!
  • 每条记录存储一个图像,方法WriteFile用于将100个图像写入一个特殊文件。所以当多线程尝试同时将图像写入同一个文件时发生异常。我认为这可能是线程死亡的原因
【解决方案2】:

正如 cmets 中所提到的,只要队列中有元素,您的线程就会存活,一旦它们都被清空,线程就会终止。这可以解释为什么您在调试时只看到一个活动线程。

您的问题的一个潜在答案是使用 System.Collections.Concurrent 类中的 BlockingCollection 而不是队列。它具有执行阻塞出队的能力,这将停止线程,直到有更多元素可用于处理。

另一个问题是 eQeiQ 之间的良好竞争条件 - 考虑使用具有 Tuple 或自定义数据类型的单个队列,以便您可以将两者都出队 newRecordnewRecordImage 在一个操作中。

【讨论】:

  • 我的队列增加得非常快,大约 1000/12s。所以没有机会队列用完元素。
  • 啊,那你一定要注意比赛条件!
猜你喜欢
  • 1970-01-01
  • 2018-04-11
  • 2019-08-08
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多