有没有一种方法可以处理任何类型的集合,而不是仅仅依赖Array、List等
本文关键字:集合 依赖 List Array 类型 一种 方法 任何 处理 有没有 | 更新日期: 2023-09-27 17:59:38
此示例适用于一个名为"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();