0

简化的 7 个步骤:

  1. [MainForm] 用户点击 btnAdd 按钮
  2. 将显示 AddForm
  3. [AddForm] btnCreate 被点击
  4. 在 btnCreate_Click 中,我们使用等待器运行 AddProductProcess * 我们将在单击后立即关闭 AddForm *并显示 MainForm
  5. 在 AddProductProcess 中,我们使用 awaiter 运行 AddProduct
  6. 我们运行 AddProduct 它将为我们完成漫长的过程并填充应用程序级静态集合:ProductCollection
  7. [MainForm] 处理 AddProduct 完成后,我们将在 lstProducts 列表框中显示已添加的产品项。

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);

对这段代码和主题的任何想法表示赞赏,

4

1 回答 1

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);
}

最后一个方法只是在任务上运行,所以它是一个“正常”的跨线程错误。您可以使用正常方式解决它,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);
}
于 2012-06-03T10:32:26.347 回答