C# 多线程处理,可同时访问列表框>数据丢失(选取/删除)



我有一个包含url列表的ListBox。

我有两个线程接受这些url并将它们处理成一个函数。

我的线程1取ListBox的items[0],我的线程2取items[1]

Thread捡起物品后,立即使用Items.RemoveAt(0 or 1)将其移除

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

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

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

Thanks in advance

编辑:使用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();
        });
    }

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

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

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

是的,这是因为您没有同步访问列表。

基本阅读文档c#,锁语句。在访问列表时设置锁。这可以防止多个线程同时访问它。

然后你总是得到顶部的项目(items[0]),立即删除它。

我不太熟悉多线程

我真的很喜欢人们表现出这种态度。你能想象一个厨师,作为一个专业厨师在餐厅工作,说"啊,我不熟悉烤箱,你知道的"。或者医生说:"好吧,我这里有个问题,我不知道怎么打针。"考虑到今天我们生活在一个五彩缤纷的世界,这句话只是一种不好的尖叫。

相关内容

  • 没有找到相关文章

最新更新