110,533
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadStudy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10000; i++)
{
Person p = new Person(i, "刘备"+i.ToString(), "liubei123456");
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc),p);
}
}
private delegate void MyInvokeDelegate(object name);
private void Test(object o)
{
Person p = o as Person;
listView1.Items.Add(new ListViewItem(new string[] { p.Id.ToString(), p.Name, Thread.CurrentThread.ManagedThreadId.ToString() }));
}
public void ThreadFunc(object b)
{
MyInvokeDelegate myInvoke = new MyInvokeDelegate(Test);
this.BeginInvoke(myInvoke, b);
}
}
public class Person
{
public Person(int id, string name,string password) { Id = id; Name = name;Password = password; }
public int Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
}
}
private void Test(object o)
{
Person p = o as Person;
listView1.Items.Add(new ListViewItem(new string[] { p.Id.ToString(), p.Name, Thread.CurrentThread.ManagedThreadId.ToString() }));
listView1.Update();
}
先告诉你为什么,因为你每次更新后,ListView.Item更新了,界面还没有更新,所以要等你所有循环结束,再次进入消息循环才可以刷新显示。那么最直接的做法就是在你的item变化后,调用一次ListView的Update方法。
可是这样做,直接的结果就是闪烁的发生,你根本看不清更新的数据。
进一步的做法就是自己写一个DoubleBufferListView类继承系统的ListView
public class DoubleBufferListView : ListView
{
public DoubleBufferListView()
{
SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint, true);
UpdateStyles();
}
}
用这个替换掉你界面的ListView即可,最简单做法直接去修改你的Form1.Designer.cs文件,找到定义,修改为DoubleBufferListView类型。
至此,实现你的效果,并且不闪烁。
另外多给你回答一个,免得你等下还要问
如果你希望新添加的可以优先看到,有滚动的效果,可以增加一行,修改为如下:
private void Test(object o)
{
Person p = o as Person;
listView1.Items.Add(new ListViewItem(new string[] { p.Id.ToString(), p.Name, Thread.CurrentThread.ManagedThreadId.ToString() }));
listView1.EnsureVisible(listView1.Items.Count - 1);
listView1.Update();
}
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Test("测试1",10);
Test("测试2",10);
Test("测试3",10);
Test("测试4",10);
Test("测试5",10);
}
Random rnd = new Random();
async void Test(string title, int numbers)
{
for (var i = 1; i <= numbers; i++)
{
var n = rnd.Next(1000);
this.listBox1.Items.Add($"从“{title}”写入第{i}个内容,然后等待{n}毫秒");
await Task.Delay(n);
}
}
}
}
你可以看到,这里模拟5个“独立并发的”任务,分别循环10此写入内容,它们操纵之间不卡顿,你可以拖动窗体,可以干别的事情。