2012-06-20 41 views
2

我有以下代碼:Parallel.ForEach與ListView的

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

,我得到以下編譯錯誤:

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.

我搜索有關如何使用列表視圖與任務,但couldn」找不到任何東西。

如何在ListView中使用Parallel.ForEach?

+0

這是編譯? –

+0

不,我得到那個錯誤 –

+0

正確的理由是因爲CheckedItems集合就是這樣一個集合,所以它不能「推斷」這個類型。集合的基本類型是什麼? –

回答

8

ListView.CheckedItems返回一個CheckedItemsListViewCollection,它沒有實現任何泛型集合類型,因爲它駐留在.NET 1.x領域,泛型尚不可用。您需要告訴PLinq集合中存在哪些類型的項目。如果您閱讀文檔,CheckedListViewCollection包含ListViewItems。您可以使用Linq通過使用Cast擴展方法顯式指定類型。

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

這整個的討論可能會變得過時,因爲列表視圖(因此,大多數其他的WinForm控件)只能從UI線程訪問。如果你必須並行執行,你可以在ListViewItem中創建一個數據的副本並處理它。

+0

這工作完美 –

+1

我寧願使用'Cast'而不是'OfType'。如果你使用'OfType'並錯誤地指定了不正確的類型,它將默默地返回一個空集合。但是'cast'會大聲地失敗,並且會有一個例外,這會更好,因爲你馬上就會看到你的錯誤。 – svick

+1

@svick - Spot on,我的意圖是使用cast(請參閱說明),但在輸入代碼示例時,我錯誤地使用了OfType。我會馬上改變它 – Polity

1

將代碼更改爲以下內容。請注意,爲此,由於Cast擴展方法的原因,您需要爲System.Linq添加using語句。

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

這應該編譯,因爲您明確定義類型,因爲CLR無法從非泛型集合中推斷出類型。

+0

現在編譯就好了。謝謝! –

+0

但我無法使用item.subitems和這個答案 –

+3

該集合包含'LIstViewItem's,而不是'string's,所以你的代碼在運行時會失敗並出現異常。 – svick