2012-11-26 39 views
2

我有一個ListView,我用大量項目填充超過3000.這可能需要長達15秒。 每次我添加一個項目時,我想更新一個標籤,說明到目前爲止已添加了多少項目。 要做到這一點我用這個代碼:C# - 添加項目到ListView時更新標籤

foreach (FileInfo f in dir.GetFiles("*.*", SearchOption.AllDirectories)) 
{ 
    DateTime dt = GetDateTakenFromImage(Path.Combine(f.Directory.ToString(), f.Name)); 
    count++; 
    labelLoadedLeft.Text = "Loading " + count + " files so far"; 
    ListViewItem lSingleItem = lv.Items.Add(f.Name); 

    lSingleItem.SubItems.Add(dt.ToString("dd MMMM yyyy")); 
    lSingleItem.Tag = Path.Combine(f.Directory.ToString(), f.Name); 
} 

不幸的是,標籤不顯示,直到所有的項目都被載入。

我知道這與我正在做一個冗長的操作在三個UI線程,我應該使用背景工作來做這項工作。

有沒有人知道如何使用後臺工作人員的優秀和簡單的例子。我迄今發現的對我來說太複雜或太複雜。

謝謝

Crouz

+0

你見過這個教程嗎? HTTP://www.dotnetperls。com/backgroundworker –

+2

除了線程之外,通過在列表視圖中調用'BeginUpdate \ EndUpdate'方法,或者使用'AddRange'一次性插入所有項目,您可以使插入操作更高效。 – Maciek

+0

是這個WPF/WinForms? – sll

回答

1

如果你只希望你的標籤進行更新,你應該更新它。

labelLoadedLeft.Text = "Loading " + count + " files so far"; 
labelLoadedLeft.Update(); 

你使用哪個版本的VS/C#?使用VS2012/C#5.0,您可以利用新的「等待」功能。它使代碼易於閱讀和更新的UI可以完成而無需調用等

+0

嗨,謝謝你的回答,這工作正常,雖然整個操作似乎有點慢,也許是我。我使用VS2010 – Crouzilles

1

你可以用BackgroundWorker來做到這一點,這裏有一個例子,http://dotnetforum.net/topic/34729-how-to-cancel-backgroundworker-during-getfiles/

但是,直到您獲得所有文件的列表後,UI纔會顯示任何內容。正如你所說這很慢。

使用EnumerateFiles方法,http://msdn.microsoft.com/en-us/library/dd383458(v=vs.100).aspx,它一次返回一個文件。

+0

正如@YYY所提到的,TPL比「BackgroundWorker」更好。但是你仍然必須使用EnumerateFiles來獲得一個壓縮UI。 –

1

假設您正在使用.NET 4.0,後臺工作人員最容易通過TPL進行處理。您可以使用代碼,看起來像這樣的背景下啓動工作:

Task.Factory.StartNew(() => 
{ 
    // Background Worker Stuff goes here 
}, TaskCreationOptions.LongRunning); 

然後你可以把你的工人的工作在另一個類/函數,並將它yield return其結果從DoWork(),給你什麼的IEnumerable<T>它正在返回。使用您的foreach環比,像這樣:

foreach(var item in DoWork()) 
{ 
    // Update UI 
} 

將意味着你可以更新UI的結果回來。 Yield return將允許您在整個可枚舉返回之前處理項目。注意,儘管 - yield return隱式地在你的程序中設置了一個狀態機,所以除非你需要這樣的功能,使用這個習慣用法可能是非常浪費的。