Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在一个线程中执行这个任务要花费10倍的时间?_C# - Fatal编程技术网

C# 为什么在一个线程中执行这个任务要花费10倍的时间?

C# 为什么在一个线程中执行这个任务要花费10倍的时间?,c#,C#,我遇到了一个问题,我不知道为什么会这样。我正在将项目加载到我的listview中,因为有20.000多个项目需要添加,所以我希望在线程中执行,但与非线程相比,它需要超长的执行时间 private void mainFrm_Load(object sender, EventArgs e) { airportListView.Items.Clear(); var loadingThread = new Thread(loadData); loadingThread.Star

我遇到了一个问题,我不知道为什么会这样。我正在将项目加载到我的listview中,因为有20.000多个项目需要添加,所以我希望在线程中执行,但与非线程相比,它需要超长的执行时间

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

有人知道为什么会这样吗?我没有主意了。

我认为这是因为GUI项目试图实现线程安全。本质上,当您在另一个线程中将一个项目添加到ListView时,它很可能在每次添加项目时调用GUI线程上的一个方法,或者至少调用某种锁定机制,从而降低act中的性能

您应该在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);
    });
}
List toAdd=新列表();
私有void mainFrm_加载(对象发送方,事件参数e)
{
airportListView.Items.Clear();
var loadingThread=新线程(loadData);
加载thread.Start();
}
私有void loadData()
{
foreach(项目中的机场、机场管理器、机场)
{
var listViewItem=新的listViewItem(currAirport.Name);
listViewItem.SubItems.Add(currAirport.ID);
listViewItem.SubItems.Add(currAirport.Country);
添加(列表视图项);
}
airportListView.BeginInvoke(()=>
{
airportListView.Items.AddRange(toAdd);
});
}

让多个线程将数据插入主UI线程不会更快。如果一切顺利,UI线程将锁定每个参与线程,迫使它们一次插入一个数据。如果锁定没有发生,你将有比赛条件。您可能需要研究一种不同的方法来同时在屏幕上获取大量数据,比如使用ObjectListView。我不希望它更快,我只是希望UI在添加数据时能够响应,这就是我添加该线程的原因。目前只有一个线程将数据插入ListView,但据我所知,插入数据所需的时间不应超过没有线程的时间?@lokko为什么要在列表视图中放入20000个项目,只加载一页数据?正如Kevin所说,我的最佳猜测是,每次添加项目时,都需要暂停当前线程,2)切换到GUI线程,3)添加数据,4)释放GUI线程并返回yours@lokko不要将20000个项目加载到控件中-用户真的对它们都感兴趣吗?有一个搜索机制,只填充与搜索条件匹配的项目,或者按照johnny_5的建议应用分页效果-例如每页50条记录。谢谢!这正是我需要的,但是你应该改变airportListView.Items.AddRange(toAdd);到airportListView.Items.AddRange(toAdd.ToArray());