質問

I have a ListBox with a list of URLs.

I have 2 threads taking theses URLs and treat them into a function.

My Thread 1 takes the items[0] of the ListBox, and my Thread 2 takes the items[1].

After the Thread picked up the item, it immediately remove it using Items.RemoveAt(0 or 1)

My problem using this method is that some of the URL are treated twice, some even not.

Isnt there a way to flag an URL or something else ? I'm not so familiar with multi threading

PS: In my example i said i was using 2 threads, in reality i use 5 threads.

Thanks in advance

EDIT : Used the concurentqueue system :

    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();
        });
    }
役に立ちましたか?

解決

It sounds like you're using a UI control to coordinate tasks between multiple threads.

That is an extremely bad idea.

Instead, you should queue up the tasks into a ConcurrentQueue<T> or BlockingCollection<T>, and have other threads take items from the queue and process them.

他のヒント

Yes, that happens because oyu do not synchronize access to the list.

Basically read the documentation C#, LOCK statement. Put up a lock while accessing the list. That prevents multiple threads from accessing it at the same time.

Then you ALWAYS get the top item (items[0]) immediately removing it.

I'm not so familiar with multi threading

I really love when people show that attitude. Can you imagine a cook, working in a restaurant as a professional cook, saying "ah, I am not familiar with an oven, you know". Or a doctor saying "ok, I have a problem here, I have no real idea how to give an injection". Given that today we live in a multicolored world, this sentence just SCREAMS in a bad way.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top