c# - 线程队列进程

标签 c# multithreading queue

我正在使用 C# .Net4.0 在 vi​​sual studio 2010 中构建此程序 目标是使用线程和队列来提高性能。

我有一个需要处理的 url 列表。

string[] urls = { url1, url2, url3, etc.} //up to 50 urls

我有一个函数可以接收每个 url 并对其进行处理。

public void processUrl(string url) { 
    //some operation
}

最初,我创建了一个 for 循环来遍历每个 url。

for (i = 0; i < urls.length; i++)
    processUrl(urls[i]);

该方法有效,但程序速度很慢,因为它一个接一个地遍历 url。

所以我的想法是使用线程来减少时间,但我不太确定如何实现它。

假设我想创建 5 个线程同时处理。

当我启动程序时,它将开始处理前 5 个 url。完成后,程序开始处理第 6 个 url;当另一个完成时,程序开始处理第 7 个 url,依此类推。

问题是,我不知道如何实际创建 url 的“队列”并能够通过队列和进程。

谁能帮我解决这个问题?

-- 下午 1:42 编辑 --

我在同时运行 5 个进程时遇到了另一个问题。

processUrl 函数涉及写入日志文件。如果多个进程同时超时,它们将同时写入同一个日志文件,我认为这会引发错误。

我假设这是问题所在,因为我收到的错误消息是“该进程无法访问文件‘data.log’,因为它正被另一个进程使用。”

最佳答案

最简单的选择是只使用 Parallel.ForEach。如果 processUrl 是线程安全的,您可以这样写:

Parallel.ForEach(urls, processUrl);

我不建议限制为 5 个线程(调度程序将自动正常缩放),但这可以通过以下方式完成:

Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = 5}, processUrl);

也就是说,URL 处理就其本质而言通常是 IO 绑定(bind),而不是 CPU 绑定(bind)。如果您可以使用 Visual Studio 2012,更好的选择是对其进行修改以使用语言中新的 async 支持。这需要将您的方法更改为更类似的方法:

public async Task ProcessUrlAsync(string url)
{
    // Use await with async methods in the implementation...

然后您可以在循环中使用新的 async 支持:

// Create an enumerable to Tasks - this will start all async operations..
var tasks = urls.Select(url => ProcessUrlAsync(url));

await Task.WhenAll(tasks); // "Await" until they all complete

关于c# - 线程队列进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17493084/

相关文章:

java嵌套Map数据结构读写操作

java - Jmeter 1 线程组和多个 HttpRequest

c# - 从 List<float> 转换为 int

c# - 使用 .Net Framework .4.5.2 将消息发送到 Azure 服务总线队列

java - 多线程如何顺序处理?

c++ - 在队列中插入 vector 元素

ios - 我的 iOS 委托(delegate)方法是否应该始终在主线程上返回?

c++ - 我应该使用哪种 STL 来完成这项任务?

javascript - Moment.JS 月份的重音标记,西类牙语?

c# - 在 Bot Framework + Facebook Messenger 中随机收到 "OAuthException"