我有一个包含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]),立即删除它。
我真的很喜欢人们表现出这种态度。你能想象一个厨师,作为一个专业厨师在餐厅工作,说"啊,我不熟悉烤箱,你知道的"。或者医生说:"好吧,我这里有个问题,我不知道怎么打针。"考虑到今天我们生活在一个五彩缤纷的世界,这句话只是一种不好的尖叫。我不太熟悉多线程