有没有办法处理任何类型的集合,而不是仅仅依赖数组、列表等?

Is there a way to handle any type of collection, instead of solely relying on Array, List, etc?

此示例用于名为 "WriteLines" 的方法,该方法采用字符串数组并将它们添加到异步文件编写器。它有效,但我很好奇是否有一种有趣的方法来支持 - 任何 - 字符串集合,而不是依赖程序员转换为数组。

我想到了类似的东西:

public void AddLines(IEnumerable<string> lines)
{
    // grab the queue
    lock (_queue)
    {
        // loop through the collection and enqueue each line
        for (int i = 0, count = lines.Count(); i < count; i++)
        {
            _queue.Enqueue(lines.ElementAt(i));
        }
    }
    // notify the thread it has work to do.
    _hasNewItems.Set();
}

这似乎可行,但我不知道它有任何性能影响,也不知道任何逻辑影响(顺序发生了什么?我认为这甚至允许无序集合工作,例如 HashSet ).

是否有更容易接受的方法来实现这一点?

您已通过 IEnumerable<string> - 这意味着您可以对其进行迭代。哎呀,甚至还有一个语言功能专门 - foreach:

foreach (string line in lines)
{
    _queue.Enqueue(line);
}

与您现有的方法不同,这只会对序列进行一次迭代。您当前的代码将根据底层实现而有所不同 - 在某些情况下 Count()ElementAt 是优化的,但在某些情况下它们不是。如果您使用迭代器块并记录,您可以很容易地看到这一点:

public IEnumerable<string> GetItems()
{
    Console.WriteLine("yielding a");
    yield return "a";
    Console.WriteLine("yielding b");
    yield return "b";
    Console.WriteLine("yielding c");
    yield return "c";
}

尝试使用您当前的实现调用 AddLines(GetItems()),然后查看控制台...

由于您使用的是线程,因此还要添加此答案,请改用 ConcurrentQueue,如下所示:

// the provider method
// _queue = new BlockingCollection<string>()
public void AddLines(IEnumerable<string> lines)
{
   foreach (var line in lines)
   {
     _queue.Add(line);
   }
}

不需要锁,并且允许多个消费者和提供者,因为我们为每个添加的元素进行标记。

消费者基本上只需要做var workitem = _queue.Take();