处理BlockingCollection中的异常

时间:2017-03-23 08:09:25

标签: c#

我有一个用于处理队列的阻止BlockingCollection(即发送电子邮件)。

BlockingCollection<ItemQueue> queue = new BlockingCollection<ItemQueue>();
Thread threadQueue = new Thread(ProcessQueue);
threadQueue.Start();

private void ProcessQueue()
{
    while (true)
    {
        var item = queue.Take();

        process(item); 
    }
}

public void process(ItemQueue item)
{
    try
    {
        // do something
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

基本上我运行一个单独的线程,在那里我等待队列中的一个元素(某处有一个Add()调用)。然后我处理该项目。 此功能可能会引发异常:例如,如果我们正在讨论电子邮件,则Send()可能会失败。

我想以两种不同的方式处理这种情况,具体取决于具体的应用:

  1. 使用相同的项重复处理函数,直到完成没有任何异常
  2. 将此项目放在队列的末尾,以便稍后再试,但现在处理其他项目
  3. 是否有更好的方法可以原生处理这些行为?

1 个答案:

答案 0 :(得分:1)

这两种方法都有其缺点:

  • 第一种方法可能会无限期地停止队列,以防项目有永久交付问题
  • 第二种方法将无限期地在队列中保留一个永久传递问题的项目

更好的方法是为失败的项目建立单独的阻塞集合,将它们与异常对象一起推送到异常集合中,并忘记它们。一个单独的线程会将这些项目从队列中删除,分析异常并决定下一步该做什么。它可以安排在适当的时间重新发送,如果其失败计数低于某个固定数量,则推回该项目,将消息归档给管理员进行分析,或者根据系统的需要简单地丢弃它。