已简化的7个步骤:
5段代码:
private void btnAddProduct_Click(object sender, EventArgs e)
{
FormAddProduct fap = new FormAddProduct(SelCol);
fap.ShowDialog();
}
private async void btnCreate_Click(object sender, EventArgs e)
{
string stProduct = txtProductName.Text;
await ProductCollection.AddProductProcess(stProduct);
this.Close();
MainForm.Show();
}
public async Task AddProductProcess(string pName)
{
await Task.Factory.StartNew(() => AddProduct(pName));
// This would be our heavy process
}
public void AddProduct(string pName)
{
ProductItem p = new ProductItem();
p.Name = pName ;
p.Position = Count;
p.GetInfo(); // and some similar heavy methods are inside this
//ProductCollection.Add(p);
}
public void Add(Product product)
{
MainForm.lstProduct.Add(product.Name);
}
“MainForm.lstProduct.Add”导致invalid cross-thread operation
错误
我需要在其上添加一个任务完成通知,因此可以以正确的方式将结果添加到ListBox 你能帮我实现一下吗?
我应该将这行代码传递给在任务完成后立即执行的代码。
ProductCollection.Add(P);
对这段代码和主题的任何想法表示赞赏,
答案 0 :(得分:2)
你在某些地方使用async / await模式,但不是重要的地方......
public async Task AddProductProcess(string pName)
{
await Task.Factory.StartNew(() =>
AddProduct(pName));
}
public void AddProduct(string pName) // not async
{
...
ProductCollection.Add(p);
}
public void Add(Product product) // not async
{
MainForm.lstProduct.Add(product.Name);
}
最后一个方法只在一个Task上运行,所以它是一个'正常'的交叉线程错误。您可以使用MainForm.Invoke(...)
以正常方式解决它,但您也可以删除所有async和await关键字。
要正确使用async / await,您必须将其更改为:
public async Task AddProductProcess(string pName)
{
await AddProduct(pName);
}
public async void AddProduct(string pName)
{
ProductItem p = new ProductItem();
p.Name = pName ;
p.Position = Count;
await p.GetInfo(); // assuming this is doing the heavy work, make async
ProductCollection.Add(p);
}