When in the Random the values are 4, 20 it’s taking about 3-4 seconds before it’s start generating the random names. and then when it’s starting to generate the names sometimes it’s hanging on the same strings for some seconds before changing to new random.
if I’m changing the random values for example to 50, 500 it’s taking even more time before start generating and then as before in some cases it’s hanging on the same names strings before changing to new random.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace wpfMultiThreadListViewUpdate
{
public class Person
{
public string Name { get; set; }
}
public partial class MainWindow : Window
{
private Thread _thread;
public MainWindow()
{
InitializeComponent();
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += DispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
private void DispatcherTimer_Tick(object sender, EventArgs e)
{
_thread = new Thread(() => showSomePeople(new Random().Next(4, 20), lstvwPeople));
_thread.Start();
}
private void btnUpdate_Click(object sender, RoutedEventArgs e)
{
_thread = new Thread(() => showSomePeople(new Random().Next(4, 15), lstvwPeople));
_thread.Start();
}
private void showSomePeople(int numberToGet, ListView listvw)
{
List<Person> somePeople = getSomePeople(numberToGet);
Dispatcher.BeginInvoke(new Action(delegate()
{
listvw.ItemsSource = somePeople;
}));
}
private List<Person> getSomePeople(int numberToGet)
{
List<Person> peeps = new List<Person>();
for (int i = 0; i < numberToGet; i++)
{
peeps.Add(new Person() { Name = randomName() });
Thread.Sleep(200);
}
return peeps;
}
private string randomName()
{
const string chrs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rdm = new Random();
return new string(Enumerable.Repeat(chrs, 6)
.Select(s => s[rdm.Next(s.Length)]).ToArray());
}
}
}
>Solution :
If you want to do something on a background thread every second, you’d better use a System.Timers.Timer
. And if you don’t want any delay, you should not call Thread.Sleep
.
You probably also want to use a single instance of Random
to get better randomness.
Try this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += Timer_Elapsed;
timer.Interval = new TimeSpan(0, 0, 1).TotalMilliseconds;
timer.Start();
}
private void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
showSomePeople(new Random().Next(4, 20), lstvwPeople);
}
private void showSomePeople(int numberToGet, ListView listvw)
{
List<Person> somePeople = getSomePeople(numberToGet);
Dispatcher.BeginInvoke(new Action(delegate ()
{
listvw.ItemsSource = somePeople;
}));
}
private List<Person> getSomePeople(int numberToGet)
{
List<Person> peeps = new List<Person>();
for (int i = 0; i < numberToGet; i++)
{
peeps.Add(new Person() { Name = randomName() });
}
return peeps;
}
private readonly Random rdm = new Random();
private string randomName()
{
const string chrs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return new string(Enumerable.Repeat(chrs, 6)
.Select(s => s[rdm.Next(s.Length)]).ToArray());
}
}