Please Tell me what Am I doing wrong... Please

F

Franco, Gustavo

Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc doesn't run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be 8, if I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 
1

100

Hi Franco,

The problem is that your WaitProc is executed in the worker thread from the
thread pool (not in the thread you create in the Form1_Load that runs the
message loop).
Application.ExitThread exits the message loop in the current thread. When
called form the worker thread (from the thread pool) there is no message
loop to exit from.

My question is why do you need that message loop in the thread you created
in the Load event handler?
Usually if you need to create UI thread (thread running a message loop) you
create a form. Ofcourse you don't have to have form to send messages(I've
never tried to send thread messages in .NET so, I don't know how it handles
them)

So way you need those messahe loop. May be there is another solution to your
problem.

HTH
B\rgds
100

Franco said:
Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc doesn't run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be 8, if I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 
F

Franco, Gustavo

Hi thanks for the answer,

Why the Callback function WaitProc is executed on a new thread instead from
where it was created? (Ok, I guess the answer is .Net framework design)

I need because is a BackgroundClass (It doesn't have Form in at all, and it
can't have it) that is used to process AyncSockets and them requiere of a
messageloop to process the Callback functions.

(Just in case :) ) I don't want to use Sync Socket, Async Socket are more
efficients specially when you have a pool of them, using Sync Socket
requiere more work when is a Server Pool because for Aync Socket the State
Machine is easier to control than Sync Sockets.

Now, to the original question.

How can I execute a method on one specific thread? This thread doesn't
inherit from Form, so I can't user Invoke.Require/Invoke.

Thanks,
Gustavo.

100 said:
Hi Franco,

The problem is that your WaitProc is executed in the worker thread from the
thread pool (not in the thread you create in the Form1_Load that runs the
message loop).
Application.ExitThread exits the message loop in the current thread. When
called form the worker thread (from the thread pool) there is no message
loop to exit from.

My question is why do you need that message loop in the thread you created
in the Load event handler?
Usually if you need to create UI thread (thread running a message loop) you
create a form. Ofcourse you don't have to have form to send messages(I've
never tried to send thread messages in .NET so, I don't know how it handles
them)

So way you need those messahe loop. May be there is another solution to your
problem.

HTH
B\rgds
100

Franco said:
Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc doesn't run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be 8,
if
I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 
F

Franco, Gustavo

Somebody knows what is doing Form.InvokeRequired/Form.Invoke on
System.Windows.Forms.

Sombody has a Decompiler to take a look of it?

Thanks,
Gustavo.

P.S.: I tried use background.GetType().InvokeMember("UnloadClass), but it
calls the method on the calling thread and not on the thread where the class
were created.

100 said:
Hi Franco,

The problem is that your WaitProc is executed in the worker thread from the
thread pool (not in the thread you create in the Form1_Load that runs the
message loop).
Application.ExitThread exits the message loop in the current thread. When
called form the worker thread (from the thread pool) there is no message
loop to exit from.

My question is why do you need that message loop in the thread you created
in the Load event handler?
Usually if you need to create UI thread (thread running a message loop) you
create a form. Ofcourse you don't have to have form to send messages(I've
never tried to send thread messages in .NET so, I don't know how it handles
them)

So way you need those messahe loop. May be there is another solution to your
problem.

HTH
B\rgds
100

Franco said:
Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc doesn't run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be 8,
if
I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 
1

100

Franko,
Ok, lets get that straight. Classes don't belong to threads. So where you
create you classes has nothing to do with, which thread executes the method
in that classes. .Wndows Form controls classes as classes don't belong to
any thread either. Windows OS control, though, belong to threads. Windows
Form controls use internally Windows OS controls so they kind of belong to
the threads when it comes to updating the UI. That's why controls need those
Invoke and InvokeRequired members because if you want to update a control
you have to do it form the UI thread. Invoke just executes a method in the
UI thread created the control. Internally Invoke uses SendMessage, I
believe, it takes care of switching the threads.

Back to your question. If you want to execute a method in different thread
you have bunch of choices.
You already used the main two:
1. Create Thread object and call its Start method. The method you pass to
the constructor will run in a separate worker thread.
2. Use thread from the thread pool. You are using one of the methods for run
method by the thread from the thread pool (WaitProc).

If you use .NET socket class as AsyncSocket (BeginReceive and BeginSentTo)
you can provide a callback method. That call beck method will be executed in
a separate worker thread. And won't block the thread that has started the
receiving operation. With that class you don't need to start any message
loops. The framework takes care of all details.

HTH
B\rgds
100

Franco said:
Somebody knows what is doing Form.InvokeRequired/Form.Invoke on
System.Windows.Forms.

Sombody has a Decompiler to take a look of it?

Thanks,
Gustavo.

P.S.: I tried use background.GetType().InvokeMember("UnloadClass), but it
calls the method on the calling thread and not on the thread where the class
were created.

100 said:
Hi Franco,

The problem is that your WaitProc is executed in the worker thread from the
thread pool (not in the thread you create in the Form1_Load that runs the
message loop).
Application.ExitThread exits the message loop in the current thread. When
called form the worker thread (from the thread pool) there is no message
loop to exit from.

My question is why do you need that message loop in the thread you created
in the Load event handler?
Usually if you need to create UI thread (thread running a message loop) you
create a form. Ofcourse you don't have to have form to send messages(I've
never tried to send thread messages in .NET so, I don't know how it handles
them)

So way you need those messahe loop. May be there is another solution to your
problem.

HTH
B\rgds
100

Franco said:
Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc
doesn't
run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be 8,
if
I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 
F

Franco, Gustavo

Hi,



Thanks for the answer after read your email I see



1) I missed the MSDN section where it says,

"Calling the BeginSend method gives you the ability to send data within a
separate execution thread."



Then instead Application.Run() I called



AutoResetEvent checkEvent = new AutoResetEvet(false)



thread creation

thread.start

bla bla bla...



chechEvent.WaitOne();

object.dispose();

bla bla bla.



Cool, this worked fine, Thread was blocked and the Callback was executed on
different thread.



With this I could resolve the problem how to exit thread and dispose my
object right.



2) Execute a method on another thread.

Usually it can be something very useful for me because I have 6 threads
running.

Each thread creates a main object

Each thread expose the main object which I can use to access to his public
methods from different threads



2a) When I want to execute the method in a specific object/thread (in my
case the relation is one to one, each thread create his own object), the
thread is already created and I can't send the method to the constructor
because it is already created.

mmm... this case is not useful for me.



2b) Use thread from the thread pool like you said before with WaitProc, that
means on my call to my own "Invoke" a can send like a parameter my method to
execute and inside it signal the Event, and on the new thread (WaitProc)
execute the method.

Question:

For each call to my own Invoke is going to take a new thread from the thread
pool, is not a overhead for the framework? "I know it works"



2c) If Invoke take care of the switching then I changed a little bit my
example and in my example a inherit BackgroundClass from Control.

Create a delegate UnloadClassDelegate and point it to UnloadClassInternal

On UnloadClass I did:



Public void UnloadClass()

{

Console.WriteLine("Current Thread UnloadClass() : " +
Thread.Cur.....GetHas....

if (this.InvokeRequired)

this.Invoke(mUnloadClassDelegate)

else

UnloadClassInternal();

}



Private void UnloadClassInternal()

{

Console.WriteLine("Current Thread UnloadClassInternal() : " +
Thread.Cur.....GetHas....

}



When I execute this, doesn't care from where I call UnloadClass() always
UnloadClassInternal() is executed on the thread where the Control where
created and this not take a new thread from the thread pool. So, like you
said Invoke use SendMessage to do that.



Then if the point 2b) is positive and there is a little overhead the point
2c) is a solution to it?



Thanks,

You were useful to clear all this.


100 said:
Franko,
Ok, lets get that straight. Classes don't belong to threads. So where you
create you classes has nothing to do with, which thread executes the method
in that classes. .Wndows Form controls classes as classes don't belong to
any thread either. Windows OS control, though, belong to threads. Windows
Form controls use internally Windows OS controls so they kind of belong to
the threads when it comes to updating the UI. That's why controls need those
Invoke and InvokeRequired members because if you want to update a control
you have to do it form the UI thread. Invoke just executes a method in the
UI thread created the control. Internally Invoke uses SendMessage, I
believe, it takes care of switching the threads.

Back to your question. If you want to execute a method in different thread
you have bunch of choices.
You already used the main two:
1. Create Thread object and call its Start method. The method you pass to
the constructor will run in a separate worker thread.
2. Use thread from the thread pool. You are using one of the methods for run
method by the thread from the thread pool (WaitProc).

If you use .NET socket class as AsyncSocket (BeginReceive and BeginSentTo)
you can provide a callback method. That call beck method will be executed in
a separate worker thread. And won't block the thread that has started the
receiving operation. With that class you don't need to start any message
loops. The framework takes care of all details.

HTH
B\rgds
100

Franco said:
Somebody knows what is doing Form.InvokeRequired/Form.Invoke on
System.Windows.Forms.

Sombody has a Decompiler to take a look of it?

Thanks,
Gustavo.

P.S.: I tried use background.GetType().InvokeMember("UnloadClass), but it
calls the method on the calling thread and not on the thread where the class
were created.

100 said:
Hi Franco,

The problem is that your WaitProc is executed in the worker thread
from
the
thread pool (not in the thread you create in the Form1_Load that runs the
message loop).
Application.ExitThread exits the message loop in the current thread. When
called form the worker thread (from the thread pool) there is no message
loop to exit from.

My question is why do you need that message loop in the thread you created
in the Load event handler?
Usually if you need to create UI thread (thread running a message
loop)
you
create a form. Ofcourse you don't have to have form to send messages(I've
never tried to send thread messages in .NET so, I don't know how it handles
them)

So way you need those messahe loop. May be there is another solution
to
your
problem.

HTH
B\rgds
100

Hi, I have a question, and please I need a answer.



How can I finalize a thread running with Application.Run (I need the
message
loop!!!) without call Thread.Abort?.

I want to call Application.ExitThread in the same thread that it is
running.



So, This is my example and I don't know why WaitProc methods runs on
different thread.



I'm sending the source code, it is really a very simple source code.

1) Create a Form

2) OnFormLoad Create a Thread Background

3) OnFormClosing Destroy my Thread Background (Failing: WaitProc doesn't
run
on his own thread)

4) Close Form.



I put Console.Write Lines to identify the threads.

And I got this.



Current Thread Load : 7
Current Thread EntryPoint : 8
Current Thread Constructor() : 8
Current Thread Closing : 7
Current Thread Unload() : 7
Current Thread WaitProc() : 10 <====== Here Why is 10, it should be
8,
if
I
call Application.ExitThread on thread 10 I can't exit from thread 8.



So, this application hangs.



Please take a look of the example, it is very simple don't close the mail
yet, I don't know what else to do to for execute a method on his own
thread,
because that's everything I need. How do I execute a method on his own
thread (without inherit from Form and user Invoke.Required, Invoke)



Thanks so much,

Gustavo.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;



namespace Test
{
public class BackgroundClass
{
private AutoResetEvent checkEvent = new AutoResetEvent(false);



public BackgroundClass()
{
Console.WriteLine("Current Thread Constructor() : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
ThreadPool.RegisterWaitForSingleObject(checkEvent, new
WaitOrTimerCallback(WaitProc), null, -1, true);
}



private void WaitProc(object state, bool timedOut)
{
Console.WriteLine("Current Thread WaitProc() : " +
Thread.CurrentThread.GetHashCode()); // Returned 10 "WHY."
Application.ExitThread();
}



public void UnloadClass()
{
checkEvent.Set();
Console.WriteLine("Current Thread Unload() : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
}
}



public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;
private static BackgroundClass background = null;
private Thread newThread = null;



public Form1()
{
InitializeComponent();
}



protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}



#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Closing += new CancelEventHandler(Form1_Closing);
this.Load += new EventHandler(Form1_Load);
this.Text = "Form1";
}
#endregion



private static void ThreadEntryPoint()
{
Console.WriteLine("Current Thread EntryPoint : " +
Thread.CurrentThread.GetHashCode()); // Returned 8
background = new BackgroundClass();
Application.Run();
}




private void Form1_Load(object sender, EventArgs e)
{
Console.WriteLine("Current Thread Load : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
newThread = new Thread(new ThreadStart(ThreadEntryPoint));
newThread.Start();



}



private void Form1_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("Current Thread Closing : " +
Thread.CurrentThread.GetHashCode()); // Returned 7
background.UnloadClass();
}




[STAThread]
static void Main()
{
Application.Run(new Form1());
}



}
}
 

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