473,794 Members | 2,708 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Asynchronous Delegates always using same worker thread

I've been running many tests of the Asynchronous Delegate technique
and I find that although BeginInvoke() does queue the method delegate
onto a worker thread, it always does so on the _same_ thread. So if I
call BeginInvoke() three times in a row, the method delegates are
queued to the same thread and the second method doesn't begin until
the first method completes, and the third doesn't begin until the
second completes.

This occurs whether I detect completion through callback,
AsyncWaitHandle , or polling. It occurs no matter whether the delegate
refers to the same instance method or different instance methods.

The bottom line is that I don't get multi-threaded behavior, but only
two-threaded behavior.

I believe this is not the intended behavior. Has anyone else seen
this? Does anyone know why this is happening?

--
Dave Hein
Nov 16 '05 #1
4 2197
Not sure what you are exactly doing in your method, but this is the normal
behavior when:
1 - the method returns before it consumed it's CPU quota (this without
executing a blocking call) AND
2 - you run this on a single CPU machine.

Willy.
"Coot" <dh***@acm.or g> wrote in message
news:a3******** *************** ***@posting.goo gle.com...
I've been running many tests of the Asynchronous Delegate technique
and I find that although BeginInvoke() does queue the method delegate
onto a worker thread, it always does so on the _same_ thread. So if I
call BeginInvoke() three times in a row, the method delegates are
queued to the same thread and the second method doesn't begin until
the first method completes, and the third doesn't begin until the
second completes.

This occurs whether I detect completion through callback,
AsyncWaitHandle , or polling. It occurs no matter whether the delegate
refers to the same instance method or different instance methods.

The bottom line is that I don't get multi-threaded behavior, but only
two-threaded behavior.

I believe this is not the intended behavior. Has anyone else seen
this? Does anyone know why this is happening?

--
Dave Hein

Nov 16 '05 #2
"Willy Denoyette [MVP]" <wi************ *@pandora.be> wrote in message news:<eg******* *******@TK2MSFT NGP12.phx.gbl>. ..
Not sure what you are exactly doing in your method, but this is the normal
behavior when:
1 - the method returns before it consumed it's CPU quota (this without
executing a blocking call) AND
2 - you run this on a single CPU machine.

Willy.


Yes, it is a single CPU machine _BUT_ no the method doesn't return
that quickly.

Here is the method:

public int TestMethod( TimeSpan callDuration, out int threadId )
{
threadId = AppDomain.GetCu rrentThreadId() ;

int myThreadId = threadId;
int count = 10;
TimeSpan subDuration = TimeSpan.FromTi cks( callDuration.Ti cks /
count );
Type t = this.GetType();
for (int i = 0; i < count; ++i)
{
Thread.Sleep( subDuration );
Console.WriteLi ne(
"[" + myThreadId.ToSt ring() + "] "
+ t.FullName + ".TestMetho d(): " + DateTime.Now.Ti meOfDay + " "
+ i.ToString() );
}

return threadId;
}
I'm invoking it with call durations of 0.5 to 1.0 seconds.

The problem occurs if I create a delegate for this method and then use
the BeginInvoke() method of the delegate.

Note: I've also created another class that provides a threaded
implementation that calls that same method via a custom
BeginTestMethod () (and returns results through a custom
EndTestMethod() ) -- when I create thread in my custom method I can get
a large number of these TestMethods() executing concurrently -- on my
single CPU box.

But using the async delegate and BeginInvoke(), all I can do is queue
multiple invocations, but they all end up executing, in sequence, on
the same worker thread. :-(

--
Dave Hein

[snip]
Nov 16 '05 #3

"Coot" <dh***@acm.or g> wrote in message
news:a3******** *************** ***@posting.goo gle.com...
"Willy Denoyette [MVP]" <wi************ *@pandora.be> wrote in message
news:<eg******* *******@TK2MSFT NGP12.phx.gbl>. ..
Not sure what you are exactly doing in your method, but this is the
normal
behavior when:
1 - the method returns before it consumed it's CPU quota (this without
executing a blocking call) AND
2 - you run this on a single CPU machine.

Willy.


But using the async delegate and BeginInvoke(), all I can do is queue
multiple invocations, but they all end up executing, in sequence, on
the same worker thread. :-(

--
Dave Hein

[snip]

Well, this code:

using System;
using System.Threadin g;
namespace Willys
{
class Tester
{
static void Main()
{
Target t = new Target();
t.SpawnEm();
}
}
}

public class Target {
public delegate int LaunchProc(Time Span ts, out int v);
public int TestMethod( TimeSpan callDuration, out int threadId )
{
threadId = AppDomain.GetCu rrentThreadId() ;
int myThreadId = threadId;
int count = 10;
TimeSpan subDuration = TimeSpan.FromTi cks( callDuration.Ti cks /count );
Type t = this.GetType();
for (int i = 0; i < count; ++i)
{
Thread.Sleep( subDuration );
Console.WriteLi ne("[" + myThreadId.ToSt ring() + "] "
+ t.FullName + ".TestMetho d(): " + DateTime.Now.Ti meOfDay + " "
+ i.ToString() );
}
return threadId;
}
public void SpawnEm() {
int count = 2;
IAsyncResult[] asr = new IAsyncResult[count];
int threadId = 0;
LaunchProc pfn = new LaunchProc(this .TestMethod);
for (int t = 0; t< count; t++) {
asr[t] = pfn.BeginInvoke (new TimeSpan(200000 00),out threadId, null,
null);
}
foreach(IAsyncR esult ar in asr)
{
pfn.EndInvoke(o ut threadId, ar);
Console.WriteLi ne("Thread [{0}] Done", threadId);
}
}
}

Gives this:
[2856] Target.TestMeth od(): 19:03:39.044865 6 0
[2856] Target.TestMeth od(): 19:03:39.245153 6 1
[2856] Target.TestMeth od(): 19:03:39.445441 6 2
[2976] Target.TestMeth od(): 19:03:39.545585 6 0
[2856] Target.TestMeth od(): 19:03:39.645729 6 3
[2976] Target.TestMeth od(): 19:03:39.745873 6 1
[2856] Target.TestMeth od(): 19:03:39.846017 6 4
[2976] Target.TestMeth od(): 19:03:39.946161 6 2
[2856] Target.TestMeth od(): 19:03:40.046305 6 5
[2976] Target.TestMeth od(): 19:03:40.146449 6 3
[2856] Target.TestMeth od(): 19:03:40.246593 6 6
[2976] Target.TestMeth od(): 19:03:40.346737 6 4
[2856] Target.TestMeth od(): 19:03:40.446881 6 7
[2976] Target.TestMeth od(): 19:03:40.547025 6 5
[2856] Target.TestMeth od(): 19:03:40.647169 6 8
[2976] Target.TestMeth od(): 19:03:40.747313 6 6
[2856] Target.TestMeth od(): 19:03:40.847457 6 9
Thread [2856] Done
[2976] Target.TestMeth od(): 19:03:40.947601 6 7
[2976] Target.TestMeth od(): 19:03:41.147889 6 8
[2976] Target.TestMeth od(): 19:03:41.348177 6 9
Thread [2976] Done

So you see clearly that two threadpool threads are activated.

Willy.
Nov 16 '05 #4
Willy,

The behavior seems to be related to how quickly the threads execute.

I modified your code, which uses a 2-second thread duration, to make 3
calls instead of two. All three were executed on a different thread.

However, I then changed it to a 0.2-second thread duration. This time
all 3 calls executed in sequence on the same thread.

And finally, I hunted for the sweet spot and found that with a 0.5
thread duration, the first and second calls executed on different
threads, but the 3rd executed on the same thread as the first.

Not sure why there is some delay in scheduling onto a new thread, but
it seems that the first request is executed immediately, the second is
executed after waiting a 2 or 3 tenths of a second, and the 3rd is
executed after waiting 5 tenthds of a second. Since all were
dispatched within microseconds of each other, I don't understand why
the delay in initiating their execution.

Perhaps this is a tunable policy of the thread pool manager???

--
Dave Hein

"Willy Denoyette [MVP]" <wi************ *@pandora.be> wrote in message news:<u8******* *******@TK2MSFT NGP12.phx.gbl>. ..
[snip]
Well, this code:

using System;
using System.Threadin g;
namespace Willys
{
class Tester
{
static void Main()
{
Target t = new Target();
t.SpawnEm();
}
}
}

public class Target {
public delegate int LaunchProc(Time Span ts, out int v);
public int TestMethod( TimeSpan callDuration, out int threadId )
{
threadId = AppDomain.GetCu rrentThreadId() ;
int myThreadId = threadId;
int count = 10;
TimeSpan subDuration = TimeSpan.FromTi cks( callDuration.Ti cks /count );
Type t = this.GetType();
for (int i = 0; i < count; ++i)
{
Thread.Sleep( subDuration );
Console.WriteLi ne("[" + myThreadId.ToSt ring() + "] "
+ t.FullName + ".TestMetho d(): " + DateTime.Now.Ti meOfDay + " "
+ i.ToString() );
}
return threadId;
}
public void SpawnEm() {
int count = 2;
IAsyncResult[] asr = new IAsyncResult[count];
int threadId = 0;
LaunchProc pfn = new LaunchProc(this .TestMethod);
for (int t = 0; t< count; t++) {
asr[t] = pfn.BeginInvoke (new TimeSpan(200000 00),out threadId, null,
null);
}
foreach(IAsyncR esult ar in asr)
{
pfn.EndInvoke(o ut threadId, ar);
Console.WriteLi ne("Thread [{0}] Done", threadId);
}
}
}

Gives this: [snip] Thread [2856] Done [snip] Thread [2976] Done

So you see clearly that two threadpool threads are activated.

Willy.

Nov 16 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2163
by: Joey Powell | last post by:
Re: Original post = Windows forms - how do I get them to render/update properly? from August 22. Okay I am making some progress with being able to use delegates to run my shelled processes on worker threads. Yes I have gotten it to work, kind-of - that is I have gotten the shelled processes off of the UI thread (I think?). But the UI still is not updating properly! Still I have white boxes for forms, label text that does not update, and...
4
5435
by: Matthew Groch | last post by:
Hi all, I've got a server that handles a relatively high number of concurrent transactions (on the magnitude of 1000's per second). Client applications establish socket connections with the server. Data is sent and received over these connections using the asynchronous model. The server is currently in beta testing. Sporadically over the course of the day, I'll observe the thread count on the process (via perfmon) start climbing....
1
2841
by: Natalia DeBow | last post by:
Hi, I am working on a Windows-based client-server application. I am involved in the development of the remote client modules. I am using asynchronous delegates to obtain information from remote server and display this info on the UI. From doing some research, I know that the way my implementation works today is not thread-safe, because essentially my worker thread updates the UI, which is BAD. So, here I am trying to figure out how...
3
4510
by: Oscar Thornell | last post by:
Hi, I am thinking about doing all my logging asynchronously using a delegate. The main resaon for this would be performance and responsiveness of the application (an ASP.NET app). //Exampel delegate void LogDelegate(string message); LogDelegate logger = new LogDelegate(Log.Debug); logger.DynamicInvoke("Some message..");
7
3919
by: brisers | last post by:
Hello, After studying some of the available resouces ( http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/default.aspx) I can see that it is forbidden to modify the UI directly from a secondary worker thread. What I was wondering was whether I could instantiate a form within my secondary thread, get some user input and carry on until I finished? Does this break any rules of good programming conduct?
3
1970
by: Morgan Cheng | last post by:
Asynchronous I/O is said to be using native completion port. However, i checked rotor2.0 code, it seems not in stream.cs. BeginRead is defined in below way. In my understanding, If BeginInvoke is used, the task is queued; and when there is free worker thread in ThreadPool, the task is performed in specified worker thread. Then, Asynchronous I/O doesn't save thread in ThreadPool. Is my understanding correct?
4
4078
by: Morgan Cheng | last post by:
Since ASP.NET 2.0, asynchronous web service client can be implemented with event-based pattern, instead of original BeginXXX/EndXXX pattern. However, I didn't find any material about event-based server side asynchronous web service. So, we can only implement asynchronous webmethod with BeginXXX/EndXXX pattern, right? I don't why ASP.NET 2.0 don't provide event-based server side pattern.
3
4754
by: =?Utf-8?B?Sm9obg==?= | last post by:
Hi, I need to write asynchronous HTTPModule which will sometimes execute long job. I've written it using AddOnBeginRequestAsync but it still executes synchronously - I am checking performance counters but after running X requests which executes this "asynchronous" module all other requests go to application queue - so it executes synchronously. Code is based on the following article...
0
1274
by: alan | last post by:
Hello all, I'd like to ask recommendations about a "good" generic asynchronous I/O library for C++. By generic I mean, something I can use even on files, stdin/stdout, and sockets. I've seen boost::asio, and also ioxxx, but most of the examples I've seen with them are about sockets. Can they be used for general i/o (files, terminal)? Can anyone point me to good tutorials about using them for stuff other than sockets? My use case...
0
9671
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9518
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10161
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9035
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7538
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5436
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5560
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3720
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2919
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.