Threading question - please help!

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello

I hope someone could help me

I'm trying to prevent code from running before the thread I created completes. Here's the code snippet

DataTransformerWorker dtw = new DataTransformerWorker(strApplicationFolder, strSupplier
strFile, lblProgress, ProgressBar1)
//create new threa
ThreadStart tdStart = new ThreadStart(dtw.StartProcess)
Thread td = new Thread(tdStart)
td.Start()

*** I want to prevent the code below from running before the td thread complete

BindDataGridResults()
Cursor.Current = Cursors.Default
btnImport.Enabled = true

I don't know before hand how long the td thread lasts. Any suggestions

Thanks
Edward
 
Off the top of my head, is there a thread join() method in C#? Why are you threading if you're not going to run them in parallel in the first place?
 
Hi,

The simpliest way is to to Thread.Join. But this will pause also calling
thread.
Other solution might be that worker thread invokes a delegate when it
finishes.
It depends on your problem.
Where is your code block that shouldn't be executed located?
--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Edward said:
Hello,

I hope someone could help me.

I'm trying to prevent code from running before the thread I created
completes. Here's the code snippet:
DataTransformerWorker dtw = new
DataTransformerWorker(strApplicationFolder, strSupplier,
 
Thanks for the reply..

You're right calling Thread.Join will pause the calling thread which I don't want. The code block that shouldn't be executed is

BindDataGridResults()
Cursor.Current = Cursors.Default
btnImport.Enabled = true

and is located in the same method

The scenario is, when I click on the import button on the form, the new thread is created. Calling join then would mean that the user won't be able to interact with the form until the thread completes. I will put a "cancel" button on the form, but how can the user click on cancel when the user won't accept user interaction since the form thread has been suspended

Thanks

----- Miha Markic [MVP C#] wrote: ----

Hi

The simpliest way is to to Thread.Join. But this will pause also callin
thread
Other solution might be that worker thread invokes a delegate when i
finishes
It depends on your problem
Where is your code block that shouldn't be executed located
--
Miha Markic [MVP C#] - RightHand .NET consulting & developmen
miha at rthand co
www.rthand.co

Edward said:
DataTransformerWorker(strApplicationFolder, strSupplier
 
Edward said:
Hello,

I hope someone could help me.

I'm trying to prevent code from running before the thread I created completes. Here's the code snippet:

DataTransformerWorker dtw = new DataTransformerWorker(strApplicationFolder, strSupplier,
strFile, lblProgress, ProgressBar1);
//create new thread
ThreadStart tdStart = new ThreadStart(dtw.StartProcess);
Thread td = new Thread(tdStart);
td.Start();

*** I want to prevent the code below from running before the td thread completes

BindDataGridResults();
Cursor.Current = Cursors.Default;
btnImport.Enabled = true;

I don't know before hand how long the td thread lasts. Any suggestions?

td.Join(); // block until thread td ends

Look at the docs for Thread.Join() for information on the overload that
lets you timeout the blocking call so you can handle a block that lasts
too long cleanly.
 
Edward said:
Thanks for the reply...

You're right calling Thread.Join will pause the calling thread which I don't want. The code block that shouldn't be executed is:

BindDataGridResults();
Cursor.Current = Cursors.Default;
btnImport.Enabled = true;

and is located in the same method.

Then put this entire block of code (everything that responds to the
button) in a thread, instead of just part of it. That can get tricky
though with getting back to the UI thread, so a better solution is
probably to just have the thread callback on a delegate to the UI thread
which can then update your form with the results.
 
Thanks Kevin

I wish I knew more about threading... but can you give me an example of how to have the thread call back on a delegate to the UI thread?

Thanks

----- Kevin P. Fleming wrote: ----

Edward wrote
Thanks for the reply..
Cursor.Current = Cursors.Default
btnImport.Enabled = true

Then put this entire block of code (everything that responds to the
button) in a thread, instead of just part of it. That can get tricky
though with getting back to the UI thread, so a better solution is
probably to just have the thread callback on a delegate to the UI thread
which can then update your form with the results
 
Edward said:
I wish I knew more about threading... but can you give me an example of how to have the thread call back on a delegate to the UI thread?

The code that creates the thread needs to pass it a delegate to another
function in the same type instance (object, which is presumably a Form).
The function that can then use this.Invoke(...) to call yet another
method on the Form that actually does the UI work. This last method will
be run on the UI thread, not the worker thread, because of using
this.Invoke(...) to call it.

There are examples of this in the MSDN documentation, and in the
archives of this newsgroup (groups.google.com).
 
I wish I knew more about threading... but can you give me an example of
how to have the thread call back on a delegate to the UI thread?

It's pretty easy thing to do when you know it well..

What you need to do is, to initialize a thread that does some stuff, then
updates the UI. You can do it many ways, but the most appropriate one is to
let the wroker thread do what it does for living, and then upon exit as long
as it has access to the calling from, it should invoke a function that
updates the user interface.

And you know, a delegate is just a handsom pointer to function.

Note that there is an "Invoke" function which is member of any windows
form/control, so that you can "Invoke" delegates on the main UI thread.
This function takes a delegate as argument and executes that delegated
function on the main thread...

So, Let's say that your function that updates the UI upon thread exit is:

public void UpdateUI()
{
BindDataGridResults();
Cursor.Current = Cursors.Default;
btnImport.Enabled = true;
}

to define a delegate that could point to this function you need the
following delegate signature:

public delegate void UpdateUIDelegate();



and how do you initialize a variable of that delegate type that points to
the mentioned function?:

UpdateUIDelegate delegatedFunc = new UpdateUIDelegate( UpdateUI );

and how the thread can safely call this function when using that delegate?:

myForm.Invoke( delegatedFunc );



We can put it all together in a simple manner:



public delegate void UpdateUIDelegate();
public class MyForm : System.Windows.Forms.Form
{
private UpdateUIDelegate _delegatedFunc = null;
//
// <Init code and other stuff snipped or unkonown>
// </>
public MyForm ()
{
}

public void TheMethodYouAreTalkingAbout()
{
//
_delegatedFunc = new UpdateUIDelegate( UpdateUI );
System.Threading.Thread worker = new System.Threading.Thread( new
ThreadStart(ThreadFunc) );
worker.Start();
// Do nothing afterwards..
}

public void ThreadFunc()
{
try
{
// Do your thrad work here, ..
// ..
// ..
}
catch(ThreadAbortException)
{
// Handle thread abort here ..
}
// Done with your work??
if ( _delegatedFunc != null )
this.Invoke( _delegatedFunc );
}

public void UpdateUI()
{
BindDataGridResults();
Cursor.Current = Cursors.Default;
btnImport.Enabled = true;
}
}

There are really cool articles on this particular subject, but I hope you
don't mess Chris Sells':

http://msdn.microsoft.com/vcsharp/using/columns/wonders/default.aspx?pull=/l
ibrary/en-us/dnforms/html/winforms06112002.asp


http://msdn.microsoft.com/vcsharp/using/columns/wonders/default.aspx?pull=/l
ibrary/en-us/dnforms/html/winforms08162002.asp

http://msdn.microsoft.com/vcsharp/using/columns/wonders/default.aspx?pull=/l
ibrary/en-us/dnforms/html/winforms01232003.asp
 
activeThreads = true
while(activeThreads == true)

if(myThread.ThreadState == ThreadState.Stopped)|
(myThread.ThreadState == ThreadState.Aborted))
activeThreads = false
Thread.Sleep(200)
}
 
Back
Top