2017-10-12 47 views
-1

我遇到了一個問題,我不知道它爲什麼會發生。我正在將項目加載到我的列表視圖中,因爲有20,000多個項目需要添加,所以我想在一個線程中完成它,但是與非線程相比,執行需要超長的時間。爲什麼在線程中執行此任務需要10倍的時間?

private void mainFrm_Load(object sender, EventArgs e) 
{ 
    airportListView.Items.Clear(); 

    var loadingThread = new Thread(loadData); 
    loadingThread.Start(); 
} 


private void loadData() 
{ 
    foreach (var currAirport in Program.AirportManager.Airports) 
    { 
     var listViewItem = new ListViewItem(currAirport.Name); 
     listViewItem.SubItems.Add(currAirport.ID); 
     listViewItem.SubItems.Add(currAirport.Country); 

     airportListView.Items.Add(listViewItem); 
    } 
} 

這至少服用10倍的時間比這正需要:

private void mainFrm_Load(object sender, EventArgs e) 
{ 
    airportListView.Items.Clear(); 

    foreach (var currAirport in Program.AirportManager.Airports) 
    { 
     var listViewItem = new ListViewItem(currAirport.Name); 
     listViewItem.SubItems.Add(currAirport.ID); 
     listViewItem.SubItems.Add(currAirport.Country); 

     airportListView.Items.Add(listViewItem); 
    } 
} 

是否有人有線索,爲什麼發生這種情況?我沒有想法。

+4

使多個線程插入到主UI線程中的數據不會更快。如果一切順利,UI線程將鎖定每個貢獻線程,迫使它們一次插入一個數據。如果這種鎖定沒有發生,你會有競爭條件。您可能需要研究一種在屏幕上同時獲取大量數據的不同方式,例如使用ObjectListView。 – gunr2171

+0

我不想讓它變得更快,我只是希望UI在添加數據時能夠響應,這就是我添加該線程的原因。它目前只是一個將數據插入到ListView的線程,但據我所知,不需要比不插入線程的時間更長的時間。 – lokko

+2

@lokko你爲什麼要在列表視圖中放置20,000個項目,只加載一頁數據? –

回答

0

我相信這是因爲GUI項目試圖是線程安全的。從本質上講,當你在另一個線程中向ListView添加一個項目時,它很可能會在每次添加項目時在GUI線程上調用一個方法,或者至少調用某種類型的鎖定機制,從而降低性能法案。

您應該對GUI線程上的GUI項目執行操作。

如果您希望GUI在添加時具有響應性,請收集所有項目,然後在全部收集後使用AddRange()。

List<ListViewItem> toAdd = new List<ListViewItem>();  

private void mainFrm_Load(object sender, EventArgs e) 
{ 
    airportListView.Items.Clear(); 

    var loadingThread = new Thread(loadData); 
    loadingThread.Start(); 
} 


private void loadData() 
{ 
    foreach (var currAirport in Program.AirportManager.Airports) 
    { 
     var listViewItem = new ListViewItem(currAirport.Name); 
     listViewItem.SubItems.Add(currAirport.ID); 
     listViewItem.SubItems.Add(currAirport.Country); 

     toAdd.Add(listViewItem); 
    } 
    airportListView.BeginInvoke(() => 
    { 
     airportListView.Items.AddRange(toAdd); 
    }); 
} 
+0

謝謝!正是我需要的,但你應該改變airportListView.Items.AddRange(toAdd); to airportListView.Items.AddRange(toAdd.ToArray()); – lokko

相關問題