Help with cross-thread UI functionality...

S

sherifffruitfly

Hi all,

I'm trying to to figure out this stuff, and I've got part of the trick
in the code below, which updates a textbox with data from another
thread. What I'd like to do is put a Pause button on my form which
basically pauses the ReadCsv() method wherever it's at. Obviously, the
Pause button would need to be responsive to the user during while
ReadCsv() is churning. How do I do this?

Thanks for any pointers (heh-heh),

cdj

===============
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using LumenWorks.Framework.IO.Csv;
using System.IO;
using System.Threading;

namespace cdjCsvTest
{
public partial class CsvTest : Form
{
public CsvTest()
{
InitializeComponent();
}

private void btn_Go_Click(object sender, EventArgs e)
{
Thread t = new Thread(ReadCsv);
t.Start();
}

private void ReadCsv()
{

CsvReader cr = new CsvReader(new StreamReader(@"c:
\myFavorite.csv"),true);

int numFields = cr.FieldCount;
string[] headers = cr.GetFieldHeaders();

string updateText = "";
int tooMuch = 200;
int curr = 0;
while (cr.ReadNextRecord() && curr<tooMuch)
{
for (int i = 0; i < numFields; i++)
{
updateText = headers + ": " + cr +
Environment.NewLine;
UpdateText(updateText);
}

UpdateText(Environment.NewLine);

curr++;
}
}

delegate void UpdateTextDelegate(string param);

private void UpdateText(string param)
{
if (this.txt_CsvText.InvokeRequired)
{
//We're in the wrong thread, so this gets us to the
right one
this.txt_CsvText.Invoke(new
UpdateTextDelegate(UpdateText), new object[] { param });
}
else
{
//Now we're in the right thread.
txt_CsvText.AppendText(param);
}
}
}
}
 
J

Jon Skeet [C# MVP]

sherifffruitfly said:
I'm trying to to figure out this stuff, and I've got part of the trick
in the code below, which updates a textbox with data from another
thread. What I'd like to do is put a Pause button on my form which
basically pauses the ReadCsv() method wherever it's at. Obviously, the
Pause button would need to be responsive to the user during while
ReadCsv() is churning. How do I do this?

The pause button will be responsive automatically, because you're
correctly not blocking the UI thread. Now all you need to do is make
ReadCsv take notice of the pause button. You'll need some kind of state
to say whether or not to pause, and you'll probably want to use
Monitor.Wait (on the ReadCsv thread) and Monitor.Pulse (on the UI
thread) when you want to "unpause".

See http://pobox.com/~skeet/csharp/threads for more information.
 
B

Bruce Wood

The pause button will be responsive automatically, because you're
correctly not blocking the UI thread. Now all you need to do is make
ReadCsv take notice of the pause button.

<snip>

You can do that by having the Pause button set some field in the
class, say this._paused = true. Then have your background thread
method poll the this._paused field at strategic intervals. If it ever
finds it set to true, then as Jon said, the method running on the
background thread should take a nap and wait for the UI thread to
"kick" it to start it again.

So, from the UI thread's point of view, turning Pause "on" means
setting this._paused to true; turning Pause "off" means setting
this._paused to false and then giving the background thread a "kick".
From the background thread's point of view, poll this._paused at
regular intervals. If it's ever true, pause and wait to be "kicked"
awake again.
 
M

Marc Gravell

You can do that by having the Pause button set some field in the
class, say this._paused = true. Then have your background thread
method poll the this._paused field at strategic intervals.

Minor note (more info in Jon's details): you should sync. around
_paused,
or mark volatile, otherwise the background thread may be keeping
a private cached copy.

Also (Bruce): I very much like the idea of Monitor.Kick(),
Monitor.KickAll() - it
seems a lot closer to how we expect it to behave <evil grin/>

Marc
 
S

sherifffruitfly

The pause button will be responsive automatically, because you're
correctly not blocking the UI thread.

Not through any genius of my own - it's the result of copying/
adjusting code that *you* provided someone else in this newsgroup -
lol!
Seehttp://pobox.com/~skeet/csharp/threadsfor more information.

It's appearing as though there are few questions I have that aren't
significantly addressed by one of your articles. I think I'll start
there in the future, before asking the group :)


Thanks for the tips everyone!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top