0

我有一个带有 URL 列表的 ListBox。

我有 2 个线程获取这些 URL 并将它们处理成一个函数。

我的线程 1 采用items[0]ListBox 的,我的线程 2 采用items[1].

线程捡起物品后,立即使用Items.RemoveAt(0 or 1)

我使用这种方法的问题是一些 URL 被处理了两次,有些甚至没有。

没有办法标记 URL 或其他东西吗?我对多线程不太熟悉

PS:在我的示例中,我说我使用了 2 个线程,实际上我使用了 5 个线程。

提前致谢

编辑:使用concurentqueue系统:

    Thread th1;
    Thread th2;
    Thread th3;
    Thread th4;
    Thread th5;
    ConcurrentQueue<string> myQueue= new ConcurrentQueue<string>();
    Int queueCount = 0;

    private void button2_Click(object sender, EventArgs e)
    {
    //initialize objects and query the database
        DBconnect conn;
        conn = new DBconnect();
        string query = "SELECT Url FROM Pages WHERE hash = ''";
        List<string> result = conn.Select(query);
        for (int i = 0; i < result.Count(); i++)
        {
    //For all rows found, add them to the queue
            myQueue.Enqueue(result[i]);
        }
    //start the 5 threads to process the queue              
        th1 = new Thread(ProcessTorrent);
        th2 = new Thread(ProcessTorrent);
        th3 = new Thread(ProcessTorrent);
        th4 = new Thread(ProcessTorrent);
        th5 = new Thread(ProcessTorrent);
        th1.Start();
        th2.Start();
        th3.Start();
        th4.Start();
        th5.Start();

    }


    private void ProcessTorrent()
    {
    //Start an unlimted task with continueWith
        Task tasks = Task.Factory.StartNew(() =>
        {
    //Check if there are still items in the queue
            if (myQueue.Count > 0)
            {
                string queueURL;
                bool haveElement = myQueue.TryDequeue(out queueURL);
        //check if i can get an element from the queue
                if (haveElement)
                {
        //start function to parse the URL and increment the number of items treated from the queue
                    get_torrent_detail(queueElement);
                    Interlocked.Increment(ref queueCount);
                    this.Invoke(new Action(() => label_total.Text = (myQueue.Count() - queueCount).ToString()));

                }
            }
        });
    //continue the task for another queue item
        tasks.ContinueWith(task =>
        {
            ProcessTorrent();
        });
    }
4

2 回答 2

3

听起来您正在使用 UI 控件来协调多个线程之间的任务。

这是一个非常糟糕的主意。

相反,您应该将任务排队到ConcurrentQueue<T>orBlockingCollection<T>中,并让其他线程从队列中获取项目并处理它们。

于 2013-01-04T19:27:35.670 回答
-2

是的,这是因为 oyu 不同步对列表的访问。

基本上阅读文档 C#, LOCK 语句。访问列表时加锁。这可以防止多个线程同时访问它。

然后,您总是会立即将顶部项目 (items[0]) 删除。

我对多线程不太熟悉

我真的很喜欢人们表现出这种态度。你能想象一个厨师,作为一名专业厨师在餐馆工作,说“啊,我不熟悉烤箱,你知道”。或者医生说“好吧,我这里有问题,我不知道如何打针”。鉴于今天我们生活在一个五彩缤纷的世界,这句话只是以一种糟糕的方式尖叫。

于 2013-01-04T19:22:59.650 回答