当项被添加到listviewcontrol时,UI冻结
本文关键字:UI 冻结 listviewcontrol 添加 | 更新日期: 2023-09-27 18:17:31
我需要更新UI 而我正在加载的东西,我已经阅读并被告知,BackgroundWorker
是正确的"工具"在Windows窗体桌面应用程序的工作。
所以现在我想知道为什么我的UI冻结而ListView
Control
更新,因为每个项目都添加到它。
private void Form1_Shown(object sender, EventArgs e)
{
if (library.Songs != null)
{
loader.Enabled = true;
worker.RunWorkerAsync();
}
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
int songCount = 0;
foreach (Song song in library.Songs)
{
songs.Add(song);
worker.ReportProgress(songCount++);
}
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
list.Items.Add(songs[e.ProgressPercentage].Artist.Name);
list.Update(); // This line is not the culprit. Removing it has no affect on the freezing.
loader.Enabled = false;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Hooray.
}
为什么我的UI冻结了,我该如何阻止它?我认为使用BackgroundWorker的全部意义就在于,当我们在做事情时,该死的UI不会冻结?!
更新:
我有一个理论,这正在发生,因为有许多文件正在加载,因此有太多的调用ReportProgress(song)
发生,所以UI更新被留在队列中等待进度调用完成。
那么,如果是这样的话,我怎么才能把它分开,让它一次处理一定比例的歌曲呢?
更新:
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Media;
namespace Play
{
public partial class Form1 : Form
{
public MediaLibrary library = new MediaLibrary();
public static List<Song> songs = new List<Song>();
public Form1()
{
InitializeComponent();
}
public void TestPlay()
{
list.BeginUpdate();
var itemsToAdd = library.Songs
.Select(x => new ListViewItem(x.Artist.Name))
.ToArray();
list.Items.AddRange(itemsToAdd);
list.EndUpdate();
}
private void Form1_Shown(object sender, EventArgs e)
{
TestPlay();
}
}
}
使用BackgroundWorker
不会给您带来太多好处(在这种情况下)。它只是将Song
添加到集合中,并要求UI线程将歌曲添加到ListView
中。
我建议你使用ListView。BeginUpdate和EndUpdate
方法,并在UI线程本身填充列表。你可以完全扔掉没有任何价值的BackgroundWorker
。
否则创建一个数组的项目,你需要添加,然后调用ListViewItems.AddRange
优化一次添加多个元素。
var itemsToAdd = library.Songs
.Select(x => new ListViewItem(x.Artist.Name))
.ToArray();
listView.Items.AddRange(itemsToAdd);