Click here to Skip to main content
14,487,203 members
Rate this:
Please Sign up or sign in to vote.
See more:
I'm polling a database every 1/2 second via Threading.Timer and displaying the results in a Windows Form listview control. The query results return about 150 rows that I initial 'ADD' to listview. Once the listview is populated I no longer 'ADD' items I iterate through each row of the listview and access the TEXT property to change the contents of each row. I do this so I won't have to clear the listview on each query causing the listview to paint and lose it's current scroll position...

The winForm is a little unresponsive. I thought if I moved the updating of the control off of the main thread that the form would say responsive and this would improve the performance.

Can someone please clarify what's going on here and what do I need to do to make the form more responsive and improve the efficiency of updating the listview with new result but without repainting the listview and losing it's current scroll position.

Thanks in advance,
-Dee
Posted
Updated 29-Apr-19 13:23pm
Comments
BillWoodruff 1-Dec-11 20:31pm
   
This may be a dumb question, but it sounds like you are not using DataBinding where any change in the underlying DataBase, ideally, is propagated to the changed segment presentation control, ideally: very quickly.

Why ?
Rate this:
Please Sign up or sign in to vote.

Solution 1

What's wrong about my solution Polling Database with Timer[^]?

If you run polling in a separate thread, UI update will go via UI thread invocation. Even it you "updating of the control off of the main thread" (I read it as "UI thread"), the actual update will happen in UI thread due to invocation. You simply cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
   
Comments
d.allen101 2-Dec-11 14:52pm
   
I'm struggling! what am I doing wrong! my listview control isnt updating and my form is freezing. here's what my code looks like:

MyDataObject myDatObj = new MyDataObject;
Thread thrd = new Thread(new ParameterizedThreadStart(ListviewMethod));
thrd.Start(myDatObj);
EventWaitHandle ewh = new AutoResetEvent(false);
delegate void ListviewDel(object dataObj);
Timer tmr = new Timer();
tmr.Interval = 500;
tmr.Tick += new EventHandler(OnListview_Tick);
tmr.Start();

void OnListviewTick(object sender, EventArgs e)
{
ewh.Set();
}

void ListviewMethod(object obj)
{
while(true)
{
ewh.WaitOne();

if(listview1.InvokeRequired)
{
listview1.Invoke((ListveiwDel)ListviewMethod, myDatObj);
continue;
}

double a = myDatObj.Number1;
double b = myDataObj.Number2;
double c = myDataObj.Number3;

listview1.Add(a);
listview1.Add(b);
listview2.Add(c);
}
}
   
You don't need ParameterizedThreadStart -- you don't use obj. ParameterizedThreadStart is bad thing. Instead, did I tell you to use thread wrapper. ListView method is non-static (instance) method, it already passed "this". Try using manual reset event. (Auto might work, too, but I did it with manual.) I don't know what else...

Oh, I see!!! Problem found!!!
In ListviewMethod, you invoke the same very method. How could you do it??!!! This method waits AGAIN. No, don't do it. Create two separate method: a separate one for UI update, and ListviewMethod should only wait and then Invoke UI update method.

I cannot stand it: such a common flaw. Why you try to "save" (something :-) on methods? Makes no sense.
--SA
d.allen101 4-Dec-11 1:49am
   
SA, I'm confused! can you I've ready your solution several times and read your articles on threading: i'm trying to implement what you suggested but I can't seem to get it right. can you point to an example that implements this please?
d.allen101 4-Dec-11 2:07am
   
is this correct? :

delegate void LstVwDel();

MyDataObj myDatObj = new MyDataObj();
LstVwDel lstVwDel = new LstVwDel(updateLv);
Thread thrd = new Thread(updateThread);
thrd.Start();
EventWaitHandle ewh = AutoResetEvent(false);
Timer tmr = new Timer();
tmr.Interval = 500;
tmr.Tick += new EventHandler(threadThrottle_Tick);
tmr.Start();

void threadThrottle_Tick(object sender, EventArgs e)
{
ewh.Set();
}

void updateThread()
{
while(true)
{
ewh.WaitOne();
Invoke(lstVwDel);
}
}

void updateLv()
{
if(listview1.Items.Count < 1)
{
listview1.BeginUpdate();

for(i = 0; i < myDatObj.Numbers.Count; i++)
{
double a = myDatObj.Number1[i];
double b = myDatObj.Number2[i];
double c = myDatObj.Number3[i]

listview1.Items.Add(a);
listview1.Items.SubItems.Add(b);
listview1.Items.SubItems.Add(c);
}
listview1.EndUpdate();
}
else
{
listview1.BeginUpdate();

for(int i = 0; i < myDatObj.Numbers.Count; i++)
{
double a = myDatObj.Number1[i];
double b = myDatObj.Number2[i];
double c = myDatObj.Number3[i];

listview1.Items[i].Text = a;
listview1.Items[i].SubItems[1].Text = b;
listview1.Items[i].SubItems[2].Text = c;
}
listview1.EndUpdate();
}
}
d.allen101 4-Dec-11 2:32am
   
that 'seems' to work but my form is VERY slugglish! and there is a lot of latency in my listview displaying the results...
Rate this:
Please Sign up or sign in to vote.

Solution 2

Try setting the double buffered property in true.

Also you could use:




this.SuspendLayout();
this.listview.SuspendLayout();


//update control  
//put listview manipulation code hrer to not cause refresh form



this.listview.ResumeLayout(false);
this.ResumeLayout(false);
   
Comments
Dave Kreskowiak 29-Apr-19 22:03pm
   
You do understand that the question you posted this to is over seven years old?
saberw 1-May-19 1:57am
   
Did you know that each question has a more correct answer without considering time.
Dear learners can use it.
Dave Kreskowiak 1-May-19 8:22am
   
Yes I know. What I also see is more information and discussion in Solution 1 than in your answer, which is just a small subset of what was discussed.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100