0

URL のリストを含む ListBox があります。

これらの URL を取得する 2 つのスレッドがあり、それらを関数として扱います。

私の Thread 1 はitems[0]ListBox の を取り、私の Thread 2 はitems[1].

スレッドがアイテムを拾った後、すぐにそれを削除しますItems.RemoveAt(0 or 1)

この方法を使用する私の問題は、URL の一部が 2 回処理され、一部は処理されないことです。

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>またはBlockingCollection<T>にキューに入れ、他のスレッドにキューからアイテムを取得して処理させる必要があります。

于 2013-01-04T19:27:35.670 に答える
-2

はい、これは oyu がリストへのアクセスを同期しないために発生します。

基本的にドキュメントC#、LOCKステートメントを読んでください。リストへのアクセス中にロックを設定します。これにより、複数のスレッドが同時にアクセスすることを防ぎます。

次に、常に一番上のアイテム(items [0])をすぐに削除します。

マルチスレッドに慣れていない

人々がその態度を示すとき、私は本当に大好きです。プロの料理人としてレストランで働いている料理人を想像できますか。または、「わかりました、ここに問題があります。注射の仕方がわかりません」と言う医師。今日、私たちは多色の世界に住んでいることを考えると、この文は悪い意味で悲鳴を上げるだけです.

于 2013-01-04T19:22:59.650 に答える