Async Delegate Execution

  • Thread starter Thread starter Vlad
  • Start date Start date
V

Vlad

I have implemented an asyncrhonous execution of a method using the
delegate's BeginInvoke()
I am trying to spin multiple worker threads in a thread pool.
Here is the code:

TestProcess process = new TestProcess(TestProcess);
process.BeginInvoke(args,null,null);

private void TestProcess(args)
{
Thread.CurrentThread.Name = "TestProcess; Group: " + args;
}

However after a while it seems that the TestProcess method starts executing
on the same thread that became inactive.
I get exceptions pointing me to the line where I assign
Thread.CurrentThread.Name as it is already assigned by the previous
execution.

Is this the correct behaviour?
While I understand that the TreadPool object could choose existing thread
resources naturally I thought that the data on that new thread would be
reset.
Is Thread.CurrentThread.Name and exclusion to that rule not not considered
to be part of the thread data?
It basically becomes useless since I cannot uniquely identify the threads
anymore...

Could you please let me know if I am doing something wrong or if that is by
design. If it is by design, please refer me to the KB article or other
resources.

Thanks,
Vlad
 
Hello Vlad,

Thanks for posting. I have done some research on your code but I still have
some difficulties understanding it. I would appreciate it very much if you
could clarify some points. What is TestProcess class? Is it derived from
the Delegate class? If yes, how do you define the BeginInvoke() method?

The Name property of a Thread can only be set once. This also applies to
ThreadPool's worker threads. If you would like to uniquely identify the
threads by their Names, you can use new threads, instead of pooling from a
ThreadPool. Currently we do not have any public KB article that addresses
the issue, however, you may refer to the MSDN library for more information
on ThreadPool and Thread.Name:

ThreadPool Class
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemthreadingthreadpoolclasstopic.asp?frame=true

Thread.Name Property
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfSystemThreadingThreadClassNameTopic.asp?frame=true

I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Sorry for not making it clear...
the TestProcess is the delegate declared like this:
delegate void TestProcess(args);

Being a delegate it has BeginInvoke() method provided by the C# compiler
that allows asynchronous execution as part of the .net Asynchronous
Execution framework.

Say the first time BeginInvoke() is called and spawn a thread. That thread
is since exited and is now inactive in a thread pool. During the first
execution the thread's Name property has been set.
The next time the BeginInvoke() is called, instead of creating the new
thread it re-used the resources of the previous thread with all thread data
(any local variables) being reset.
However the thread's name has not been reset. That kind of defeats the
purpose of using the thread name to identify threads. The name originally
given to that thread is useless in a context of new thread execution.

So here is the question...why isn't the thread's name property being reset
just like any other data within that thread so that it would look to the
code as if the thread is brand new.

Thanks!
 
Hi Vlad,

I have done some tests and it seems to me that the "BeginInvoke()" method
will not use a thread from a thread pool. I am running on Windows 2003 with
Framework 1.1. Could you paste your code that can exactly reproduce the
problem?

On the other hand, you are correct that when a used thread is returned to
the ThreadPool, its Name will not be reset. The Name property of the thread
can only be set once and even the class library cannot violate this rule. I
also believe that apart from the "Name", other properties of the thread
(e.g. Priority) will not be reset. The following is my code for testing:

using System;
using System.Threading;
public class Example
{
public static void Main()
{
for (int i = 0; i < 3; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
}
Console.WriteLine("Main thread does some work, then sleeps.");
Thread.Sleep(100000);
}
static void ThreadProc(Object stateInfo)
{
Console.WriteLine("Hello from counter "+ counter.ToString());
Console.WriteLine(Thread.CurrentThread.Priority);
counter++;
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
}
private static int counter = 0;
}

The result is the following:

Main thread does some work, then sleeps.
Hello from counter 0
Normal
Hello from counter 1
Lowest
Hello from counter 2
Lowest

It is obvious that the priority of the thread is not reset to Normal. I
look forward to your reply.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
That's fine...I just couldnt find any documentation on that if the thread
got deactivated it still retained all properties even though it is
reactivated "as new thread"
In your example the code is so fast in the for loop that the threads that
you spawn do not have a chance to complete execution before the next thread
is spawn
The better example would be:
for (int i = 0; i < 3; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
Thread.Sleep(100000)
}
Console.WriteLine("Main thread does some work, then sleeps.");
Thread.Sleep(1000000);

That way the second time a new thread is spawn the first thread has already
finished so the ThreadPool could re-use it.
Thanks for you help
 
Hello Vlad,

Thanks for your update. I agree with you that it would be better if I use
"Sleep" in my code. On the other hand, the threads also execute very
quickly and they do show that the priorities are not reset on my machine.

If you have any concerns or new findings on this issue, please feel free to
post here. Thanks again for your correction.

Have a nice day!

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Back
Top