0

簡素化された 7 つのステップ :

  1. [MainForm] ユーザーが btnAdd ボタンをクリック
  2. AddFormが表示されます
  3. [AddForm] btnCreate をクリック
  4. btnCreate_Click 内で awaiter を使用して AddProductProcess を実行 します * クリックするとすぐに AddForm を閉じます *そして MainForm を表示します
  5. AddProductProcess 内で awaiter を使用して AddProduct を実行します
  6. AddProduct を実行すると、長いプロセスが実行され、アプリケーション レベルの静的コレクション (ProductCollection) が埋められます。
  7. [MainForm] AddProduct の処理が完了すると、lstProducts ListBox に追加された製品アイテムが表示されます。

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エラーが発生する

リストボックスに適切な方法で結果を追加できるように、タスク完了通知を追加する必要があります。実装を手伝ってもらえますか?

このコード行を、タスクが終了した直後に実行されるコードに渡す必要があります。

ProductCollection.Add(p);

このコードと件名に関するアイデアは大歓迎です。

4

1 に答える 1

2

You are using the async/await pattern at some points but not where it matters...

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

That last method just runs on a Task, so it is a 'normal' cross-threading error. You can resolve it in the normal way, using MainForm.Invoke(...) but then you might as well remove all the async and await keywords.

To properly use async/await you would have to change it to something like:

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 に答える