问题
Possible Duplicate:
Most concise and proper way of avoiding cross thread operation error?
I got error when running my programs.... {"Cross-thread operation not valid: Control 'listView1' accessed from a thread other than the thread it was created on."}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
TestObject argumentTest = e.Argument as TestObject;
string[] lines = argumentTest.ThreeValue.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
foreach (string vr in lines)
{
string country = argumentTest.OneValue.Trim();
string url = vr + country + '/code/' + argumentTest.TwoValue.Trim();
string sourceCode = WorkerClass.getSourceCode(url);
document.LoadHtml(sourceCode);
var title = document.DocumentNode.SelectSingleNode("//title");
var desc = document.DocumentNode.SelectSingleNode("//div[@class='productDescription']");
//-- eksekusi title
string isititle = title.InnerText;
string isititle2 = isititle.Replace("droidflashgame: ", "");
string isititle3 = Regex.Replace(isititle2, "[^A-Za-z0-9 ]+", "");
string isititle4 = isititle3.Substring(0, Math.Min(isititle3.Length, 120));
//-- Adding to list view for next step...
ListViewItem abg = new ListViewItem(isititle3);
abg.SubItems.Add(isititle4);
listView1.Items.Add(abg); // ERROR in Here?
I knew in some tutorial said using invoke? but I tried many thing but still error?
Any hand?
回答1:
Try this .This works fine for me
ListViewItem abg = new ListViewItem(isititle3);
if (listView1.InvokeRequired)
listView1.Invoke(new MethodInvoker(delegate
{
listView1.Items.Add(abg);
}));
else
listView1.Items.Add(abg);
回答2:
Remove last line (listView1.Items.Add(abg); // ERROR in Here?) from your code and replace it with this:
AddListViewItem(abg);
Then and this method to your code:
delegate void AddListViewItemDelegate(ListViewItem abg);
void AddListViewItem(ListViewItem abg)
{
if (this.InvokeRequired)
{
AddListViewItemDelegate del = new AddListViewItemDelegate(AddListViewItem);
this.Invoke(del, new object() { abg });
}
else
{
listView1.Items.Add(abg);
}
}
This will do the job, happy codding!
回答3:
As you are using a background worker, you can simply pass the item via progress changed:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//..........
var test = new ListViewItem("test");
backgroundWorker1.ReportProgress(0, test);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listView1.Items.Add((ListViewItem)e.UserState);
}
来源:https://stackoverflow.com/questions/14019054/how-to-changing-listview-inside-backgroundworker-cross-thread-error