Kendall Hildebrandt
Kendall Hildebrandt

Reputation: 59

Parallel.ForEach with ListView

I have the following code:

Parallel.ForEach(this.listView2.CheckedItems,
                    new ParallelOptions { MaxDegreeOfParallelism = 4 },
                    (CheckedItem) =>
                    {
                         //do something
                    });

and I get the following compile error:

The type arguments for method 'System.Threading.Tasks.Parallel.ForEach(System.Collections.Concurrent.OrderablePartitioner, System.Threading.Tasks.ParallelOptions, System.Action)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

I searched about how to use listview with tasks but couldn't find anything.

How can I use Parallel.ForEach with ListView?

Upvotes: 2

Views: 2665

Answers (2)

Polity
Polity

Reputation: 15140

ListView.CheckedItems returns a CheckedItemsListViewCollection which doesn't implement any of the generic collection types since it resides from back in the .NET 1.x area where generics were not available yet. You need to tell PLinq what type of items are residing in the collection. If you read the documentation, CheckedListViewCollection contains ListViewItems. You can use Linq to explicitly specify the type by using the Cast extension method.

Parallel.ForEach(this.listView2.CheckedItems.Cast<ListViewItem>(),
                    new ParallelOptions { MaxDegreeOfParallelism = 4 },
                    (CheckedItem) =>
                    {
                         //do something
                    });

This whole discussion will probably become obsolete since ListViews (and hence, most other winform controls) can only be accessed from the UI thread. If you have to go parallel, you can create a copy of the data within a ListViewItem and work over that.

Upvotes: 8

Mike Perrenoud
Mike Perrenoud

Reputation: 67928

Change the code to the following. Please note for this to work you will need to add a using statement for System.Linq because of the Cast extension method.

Parallel.ForEach<string>(this.listView2.CheckedItems.Cast<string>(), 
    new ParallelOptions { MaxDegreeOfParallelism = 4 }, 
    (CheckedItem) => 
    { 
        //do something 
    });

That should compile because you're explicitly defining the type as the CLR cannot infer types from a non-generic collection.

Upvotes: 1

Related Questions