循环遍历列表并创建多个线程

时间:2013-04-06 12:28:30

标签: c# multithreading

我想循环浏览一个URL列表,如果网站关闭或没有使用多个线程,请检查每个URL。

我的方法:

            while (_lURLs.Count > 0)
            {
                while (_iRunningThreads < _iNumThreads)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(CheckWebsite));                        
                    string strUrl = GetNextURL();
                    if (!string.IsNullOrEmpty(strUrl))
                    {
                        t.Start(strUrl);
                        _iRunningThreads++;
                    }
                    else
                    {
                        break;
                    }
                }
            }

    private string GetNextURL()
    {
        lock (_lURLs)
        {
            if (_lURLs.Count > 0)
            {
                string strRetVal = _lURLs[0];
                _lURLs.RemoveAt(0);
                return strRetVal;
            }
            else
            {
                return string.Empty;
            }
        }
    }

线程完成后,_iRunningThreads属性会递减。

我的问题是:外部while循环阻止所有“while (_lURLs.Count > 0)”。 在外部while循环中添加Application.DoEvents()会有所帮助,但我想在c#库中使用Application.DoEvents()不可用的代码。

谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

您可以使用 TPL 而不是自己管理帖子 此外,如果您使用.Net Framework 4.5,您甚至可以添加async / await和 WhenAll 方法来阻止阻止......

这是一个小例子:

private async Task CheckUrl()
    {
        List<Task> tasks = new List<Task>();

        string url = GetNextUrl();
        while (!String.IsNullOrEmpty(url))
        {
            tasks.Add(Task.Run(() => CheckWebSite(url)));
            url = GetNextUrl();
        }

        await Task.WhenAll(tasks);

        // All tasks have finished...

    }

答案 1 :(得分:1)

我认为在这种情况下使用.NET ThreadPool是个好主意,如果任务需要很短的时间才能完成。

退房:http://msdn.microsoft.com/en-us/library/4yd16hza.aspx

这使您可以稍微简化代码,因为ThreadPool会自动管理工作线程的数量。您只需为每个URL调用ThreadPool.QueueUserWorkItem并增加一个正在运行的任务计数器。将项目排队到ThreadPool不会阻止UI线程。

让ThreadPool任务递减计数器(就像你现在一样),当计数器变为零(所有任务都已运行)时,调用回调函数,以便主代码知道何时处理了所有URL。您可以通过该回调更新UI或其他任何您想做的事情。