473,509 Members | 3,095 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inter-thread message queue in C#

les
Here's a class which uses 2.0 generics to implement an inter-thread
message queue in C#. Any number of threads can post and read from the
queue simultaneously, and the message object can be any type.

There's a test driver at the bottom which demonstrates usage.

/*-----------------------------------------------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Lib101
{
/// <summary>
/// InterthreadMessageQueue is a queue designed to be used by
multiple threads to exchange messages.
/// Any thread can post an item to the queue with PostItem(), and
any thread can retrieve items with GetItem().
/// GetItem has a maxWait parameter which specifies the amount of
time the receiving thread will block
/// waiting for an item. If this value is -1, blocking is
indefinite.
/// </summary>
public class InterthreadMessageQueue<T>
{
System.Collections.Generic.Queue<T> _queue = new
System.Collections.Generic.Queue<T>();

/// <summary>
/// Post a message to the queue.
/// </summary>
public void PostItem(T item)
{
lock (_queue)
{
_queue.Enqueue(item);
if (_queue.Count == 1)
{
Monitor.Pulse(_queue);
}
}
}
/// <summary>
/// Retrieve a message from the queue.
/// </summary>
/// <param name="maxWait">Number of milliseconds to block if
nothing is available. -1 means "block indefinitely"</param>
/// <returns>The next item in the queue, or default(T) if queue
is empty</returns>
public T GetItem(int maxWait)
{
lock (_queue)
{
if (_queue.Count == 0)
{
if (maxWait == 0)
return default(T);
Monitor.Wait(_queue, maxWait);
if (_queue.Count == 0)
return default(T);
}
return _queue.Dequeue();
}
}
}

public class InterthreadMessageQueueTester
{
static InterthreadMessageQueue<string> _testqueue = new
InterthreadMessageQueue<string>();
public static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(msgGenerator));
t1.Start();
Thread t2 = new Thread(new ThreadStart(msgGenerator));
t2.Start();

string msgid = null;
do
{
msgid = _testqueue.GetItem(8000);
Console.WriteLine("Received msgid={0}", msgid);
} while (true);

}
static void msgGenerator()
{
Thread.Sleep(5000);
for (int i = 1; i < 1000; i++)
{
string msg = string.Format("{0}.{1}",
Thread.CurrentThread.ManagedThreadId, i);
_testqueue.PostItem(msg);
Console.WriteLine("Posted msgid={0}", msg);
Thread.Sleep(15);
}
}
}

}

May 19 '06 #1
6 16690
Did you have a question?

If you are just letting people know about this wonderful solution I suggest
you post it on CodeProject.com
May 19 '06 #2

<le*@ivsds.com> wrote in message
news:11**********************@38g2000cwa.googlegro ups.com...
Here's a class which uses 2.0 generics to implement an inter-thread
message queue in C#. Any number of threads can post and read from the
queue simultaneously, and the message object can be any type.


[code snipped]

Hi les,

I was just looking at something like that a few days ago and I have a
question:

Is it possible that one of two threads waiting on an empty queue might get
stuck? Here's the scenario:

1) Queue is empty
2) T1 calls GetItem, enters Monitor.Wait
3) T2 calls GetItem, enters Monitor.Wait
4) T3 calls PostItem and calls Monitor.Pulse since the queue is empty
5) T3 calls PostItem again before T1 or T2 have a chance to run.
Monitor.Pulse doesn't get called since the queue isn't empty anyomoe
6) T1 and T2 compete for the lock, T1 wins and dequeues one item
7) T2 is now stuck in Monitor.Wait although the queue is non-empty

I'm not really sure if the above scenario can really happen and T2 would
only get stuck for "maxWait" since you don't check the return code of
Wait(). In my code I call the equivalent of "Pulse" each time I leave
GetItem to prevent stuckness.
Andrew
May 19 '06 #3

"andrew queisser" <an***************@hp.com> wrote in message
news:Cs***************@news.cpqcorp.net...

<le*@ivsds.com> wrote in message
news:11**********************@38g2000cwa.googlegro ups.com...
Here's a class which uses 2.0 generics to implement an inter-thread
message queue in C#. Any number of threads can post and read from the
queue simultaneously, and the message object can be any type.


[code snipped]

Hi les,

I was just looking at something like that a few days ago and I have a
question:

Is it possible that one of two threads waiting on an empty queue might get
stuck? Here's the scenario:

1) Queue is empty
2) T1 calls GetItem, enters Monitor.Wait
3) T2 calls GetItem, enters Monitor.Wait
4) T3 calls PostItem and calls Monitor.Pulse since the queue is empty
5) T3 calls PostItem again before T1 or T2 have a chance to run.
Monitor.Pulse doesn't get called since the queue isn't empty anyomoe
6) T1 and T2 compete for the lock, T1 wins and dequeues one item
7) T2 is now stuck in Monitor.Wait although the queue is non-empty

I'm not really sure if the above scenario can really happen and T2 would
only get stuck for "maxWait" since you don't check the return code of
Wait(). In my code I call the equivalent of "Pulse" each time I leave
GetItem to prevent stuckness.

Ok, I just verified that it can indeed happen if the priority of T1 and T2
are below that of T3.

Andrew
May 19 '06 #4

andrew queisser wrote:
Is it possible that one of two threads waiting on an empty queue might get
stuck?


Yes. But, like you said the timeout will expire and any "live locked"
consumers will eventually wake. That is unless the timeout is too long
or, worse yet, infinite. So technically this implementation is safe
for multiple producers, but only one consumer.

Brian

May 19 '06 #5
Yeh. That is one reason why it is safer to use PulseAll at the potential
risk of some slight overhead. Here is mine on the CodeProject that shows
this:
http://codeproject.com/csharp/boundedblockingqueue.asp

--
William Stacey [MVP]

"andrew queisser" <an***************@hp.com> wrote in message
news:Cs***************@news.cpqcorp.net...
|
| <le*@ivsds.com> wrote in message
| news:11**********************@38g2000cwa.googlegro ups.com...
| > Here's a class which uses 2.0 generics to implement an inter-thread
| > message queue in C#. Any number of threads can post and read from the
| > queue simultaneously, and the message object can be any type.
| >
|
| [code snipped]
|
| Hi les,
|
| I was just looking at something like that a few days ago and I have a
| question:
|
| Is it possible that one of two threads waiting on an empty queue might get
| stuck? Here's the scenario:
|
| 1) Queue is empty
| 2) T1 calls GetItem, enters Monitor.Wait
| 3) T2 calls GetItem, enters Monitor.Wait
| 4) T3 calls PostItem and calls Monitor.Pulse since the queue is empty
| 5) T3 calls PostItem again before T1 or T2 have a chance to run.
| Monitor.Pulse doesn't get called since the queue isn't empty anyomoe
| 6) T1 and T2 compete for the lock, T1 wins and dequeues one item
| 7) T2 is now stuck in Monitor.Wait although the queue is non-empty
|
| I'm not really sure if the above scenario can really happen and T2 would
| only get stuck for "maxWait" since you don't check the return code of
| Wait(). In my code I call the equivalent of "Pulse" each time I leave
| GetItem to prevent stuckness.
|
|
| Andrew
|
|
May 20 '06 #6
William Stacey [MVP] <wi************@gmail.com> wrote:
Yeh. That is one reason why it is safer to use PulseAll at the potential
risk of some slight overhead. Here is mine on the CodeProject that shows
this:
http://codeproject.com/csharp/boundedblockingqueue.asp


Alternatively, *always* pulse the monitor, whether or not the queue was
empty before.

I would also suggest going round the loop "while" the count is zero,
rather than using a single "if".

See http://www.pobox.com/~skeet/csharp/t...eadlocks.shtml (half
way down) for my implementation of a producer/consumer queue.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 21 '06 #7

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

Similar topics

1
1804
by: David M. Karr | last post by:
I've been asked to help debug a complex problem involving inter-frame references, so I just want to understand the elements involved with this. Apparently, there is a page with multiple frames,...
7
31690
by: A.M | last post by:
Hi, What is the best way to implemet Inter Process Communication in .NET ? I developed two programs and I want to have them talk to each other. Thanks, Alan
13
4099
by: Bern McCarty | last post by:
I have run an experiment to try to learn some things about floating point performance in managed C++. I am using Visual Studio 2003. I was hoping to get a feel for whether or not it would make...
0
1865
by: Hugo Ferreira | last post by:
Hi everyone! Here's the current scenario: I have a program in Python that computes something very fast (<1s), but it takes a considerable amount of time to read the startup data (>90s). Since...
7
4578
by: Sumedh | last post by:
Hi everyone There is a C# project which calls C++/CLI dll to be able to call native C++ including templates. But the C++/CLI code itself also requires the C# dll to get the types. For example: ...
1
4938
by: Laurence | last post by:
Hi folks, As I konw: database partition (aka data partition?), the database can span multiple machines; table partition, the data within a table can seperate by certain condition. How about...
8
2578
by: JamesHoward | last post by:
I am looking for a way of performing inter process communication over XML between a python program and something else creating XML data. What is the best way of performing this communication? I...
6
3688
by: ecir.hana | last post by:
Hi, let's say I have two scripts: one does some computations and the other one is a graphical front end for launching the first one. And both run in separate processes (front end runs and that it...
0
1469
by: rkprasad | last post by:
I am able to create BASIC-CLEAR-INTEGRATED sql http endpoint and consume it on a LAN. But i am not able to consume the created endpoint on inter domain network. If i create endpoint on a server...
0
2306
by: dantz | last post by:
After reading all of the materials in msdn about interprocess communication now I am confused. I hope someone can give me some enlightment. I am developing a multithreaded client-server...
0
7136
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...
0
7344
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7412
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7069
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...
0
7505
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
3216
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...
0
1570
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
775
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
441
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...

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.