473,473 Members | 2,111 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

List<T> thread safety question

Hi NG,

one more question about thread safety of generic lists.
Let's assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?

Thanks for hints and help?
Rainer
Jan 20 '06 #1
17 5301

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:ui**************@TK2MSFTNGP10.phx.gbl...
Hi NG,

one more question about thread safety of generic lists.
Let's assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?


No - it will definitely fail.

This is a classic threading problem and cobbling together a threadsafe Q<T>
is a good exercise that you should really work out for yourself.

In outline you need to protect the q whilst accessing it; have a mechanism
to block if removing from an empty q;have a mechanism to unblock other
threads when adding to a q and possibly more if you want a maximum q size.
Jan 20 '06 #2
Hi Nick,

thanks for responding!
one more question about thread safety of generic lists.
Let's assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?


No - it will definitely fail.

This is what I expected, just wanted to make sure.

Would this be thread safe?:

List<MyTyp> aList = new List<MyType>();

// one thread removes elements from the list like
Monitor.Enter(aList)
try
{
MyTyp x = aList[0];
aList.Remove(x);
}
finally{
Monitor.Exit(aList)
}

// While in the same momen a other thread adds a element like

MyType y = new MyType();
Monitor.Enter(aList)
try
{
aList.Add(y);
}
finally{
Monitor.Exit(aList);
}

Regards
Rainer
Jan 20 '06 #3

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:uW**************@TK2MSFTNGP10.phx.gbl...
Hi Nick,

thanks for responding!
one more question about thread safety of generic lists.
Let's assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?


No - it will definitely fail.

This is what I expected, just wanted to make sure.

Would this be thread safe?:

List<MyTyp> aList = new List<MyType>();

// one thread removes elements from the list like
Monitor.Enter(aList)
try
{
MyTyp x = aList[0];
aList.Remove(x);
}
finally{
Monitor.Exit(aList)
}

// While in the same momen a other thread adds a element like

MyType y = new MyType();
Monitor.Enter(aList)
try
{
aList.Add(y);
}
finally{
Monitor.Exit(aList);
}

Regards
Rainer


firstly"lock" is neater than Monitor (it uses Monitor behind the scenes)
lock(aList)
{
// do stuff
}

secondly you're solution is OK as far as it goes but it avoids the main
issue which is to do with the question "what if the list is empty when I try
to take something off it?"

1) You cannot test for empty outside of the locked region in wgich you get
the element
2) You must either return something indicating that it was empty or wait
until it isn't empty which will require the Wait and Pulse methods on the
Monitor
3) If you have a fixed length list queue then the same issues apply to the
add method

Jan 20 '06 #4

"Nick Hounsome" <nh***@nickhounsome.me.uk> wrote in message
news:yg*********************@fe3.news.blueyonder.c o.uk...

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:uW**************@TK2MSFTNGP10.phx.gbl...
Hi Nick,

thanks for responding!
one more question about thread safety of generic lists.
Let's assume a generic list:
List<MyTyp> aList = new List<MyType>();

Would it be a problem if one thread removes elements from the list like
MyTyp x = aList[0];
aList.Remove(x);

While in the same momen a other thread adds a elemen like
MyType y = new MyType();
aList.Add(y);

Is it safe to assume that these two operations in combination are OK?

No - it will definitely fail.

This is what I expected, just wanted to make sure.

Would this be thread safe?:

List<MyTyp> aList = new List<MyType>();

// one thread removes elements from the list like
Monitor.Enter(aList)
try
{
MyTyp x = aList[0];
aList.Remove(x);
}
finally{
Monitor.Exit(aList)
}

// While in the same momen a other thread adds a element like

MyType y = new MyType();
Monitor.Enter(aList)
try
{
aList.Add(y);
}
finally{
Monitor.Exit(aList);
}

Regards
Rainer


firstly"lock" is neater than Monitor (it uses Monitor behind the scenes)
lock(aList)
{
// do stuff
}

secondly you're solution is OK as far as it goes but it avoids the main
issue which is to do with the question "what if the list is empty when I
try to take something off it?"

1) You cannot test for empty outside of the locked region in wgich you get
the element
2) You must either return something indicating that it was empty or wait
until it isn't empty which will require the Wait and Pulse methods on the
Monitor
3) If you have a fixed length list queue then the same issues apply to the
add method


I should add that Pulse will work in certain circumstances PuleseAll is
required in the general case of multiple threads removing stuff from the
list
Jan 20 '06 #5
Hi Nick
firstly"lock" is neater than Monitor (it uses Monitor behind the scenes)
lock(aList)
{
// do stuff
} I (beginner as I am..) thought, this would work like a critical section,
whereas two threads would only be able to pass through the code one after
the other.
In my case I want to assure a safe Queue access.

So if I interpret your hint, lock actually really locks the object right?
In this case I will rewrite my code from Monitor -> lock Thanks for this
hint!

secondly you're solution is OK as far as it goes but it avoids the main
issue which is to do with the question "what if the list is empty when I
try to take something off it?"

Acutally my real code looks like:

Monitor.Enter(ReceiveQueue);
while(ReceiveQueue.Count>0)
{
Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.Remove(aTlg);
.......

I assume this is OK, or?

Regards
Rainer
Jan 20 '06 #6
I'm not 100% clear on your usage, but three bits of feedback;

1: If (as it appears) you are trying to remove the first item in the
List<T>, you could call RemoveAt(0)

2: under standard "Enter -> Do something -> Exit" usage, it is good practice
to "try" immediately after entering the lock, and exiting the lock in the
finally. This is actually what the lock keyword does for you.

So I would rewrite your posted code as:

lock(ReceiveQueue) {
ReceiveQueue.RemoveAt(0);
}

Much simpler (and robust).

3: if you are implementing a queue in the standard sense, why not use
Queue<T>? This has the normal Enqueue, Dequeue and Peek functions - it might
be a better starting point than List<T> for your usage.

Marc
Jan 20 '06 #7
Hi Marc,
1: If (as it appears) you are trying to remove the first item in the
List<T>, you could call RemoveAt(0) Actually I fetch the first item from the List, to process it,

Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.Remove(aTlg);
--> now the "aTlg" is processed....

Bringing up this opened my eyes on a other issue I have to take care of but
this is off subject here ;-)
(I am blocking my RecieveQueue untill all messages in it are processed.....)

2: under standard "Enter -> Do something -> Exit" usage, it is good
practice to "try" immediately after entering the lock, and exiting the
lock in the finally. This is actually what the lock keyword does for you. Good that you brought up this point!
Acually I have done it every where else this way, just not on that peace of
code I copied to the NG.
I will take care of that right next!

So I would rewrite your posted code as:

lock(ReceiveQueue) {
ReceiveQueue.RemoveAt(0);
}

Much simpler (and robust).

3: if you are implementing a queue in the standard sense, why not use
Queue<T>? This has the normal Enqueue, Dequeue and Peek functions - it
might be a better starting point than List<T> for your usage.

Actually I am working with three Lists :
- SendQueue
- ReceiveQueue
- RepeatQueue

With the RepeatQueue, I have to iterate over my whole List to search for
"Telegrams" which are some where in it and then again in some of these cases
I have to remove a "Telegram" which lays somewhere in the middle of the
list.
But you are right, for the Send- and ReceiveQueue the Queue<T> might be the
better choice.

Thans four your response!
Rainer

Jan 20 '06 #8

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:uS**************@tk2msftngp13.phx.gbl...
Hi Marc,
1: If (as it appears) you are trying to remove the first item in the
List<T>, you could call RemoveAt(0)

Actually I fetch the first item from the List, to process it,

Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.Remove(aTlg);
--> now the "aTlg" is processed....

Bringing up this opened my eyes on a other issue I have to take care of
but this is off subject here ;-)
(I am blocking my RecieveQueue untill all messages in it are
processed.....)


No it isn't off subject it is what i was getting at with Wait and Pulse.

Your code should look like:

for(;;)
{
Telegram tg = ReceiveQueue.Dequeue(); // blocks thread if empty
tg.Process(); // queue is not blocked here
}

To implement the blocking behaviour you need Wait()

Somewhere else you write:

ReceiveQueue.Enqueue(new Telegram()); // releases Dequeue() blocked on
empty q

All the locking, Pulsing and waiting should be done in yor class in your
Enqueue and dequeue methods

Jan 20 '06 #9
> Actually I fetch the first item from the List, to process it,

Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.Remove(aTlg);
--> now the "aTlg" is processed....
Well, even if you want to get the value, I would still *guess* (not proven)
that it would be quicker (nominally) to use RemoveAt - i.e.

Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.RemoteAt(0);
// blah

I haven't profiled it, but that would be my guess.
I am blocking my RecieveQueue untill all messages in it are processed.....


You could try:

while(true) {
lock(ReceiveQueue) {
if(ReceiveQueue.Count==0)
break;
Telegram aTlg = ReceiveQueue[0];
ReceiveQueue.RemoteAt(0);
}
// pulse here perhaps?
}
}

This will still loop until the queue is empty, but will lock/unlock on every
iteration, exiting when empty. It might also need a PulseAll or something at
the end of each iteration to invite the other threads to the party...

Marc
Jan 20 '06 #10
Rainer Queck wrote:
one more question about thread safety of generic lists.


<snip>

Rather than respond in detail to this and the other question you've
posted, I suggest you read up on threading in general. That way
hopefully you'll be able to come up with answers without us needing to
find out exactly what your situation is, etc.

I've got a threading tutorial at
http://www.pobox.com/~skeet/csharp/threads

Hopefully that'll provide a good starting point for you.

Jon

Jan 20 '06 #11
Hi Jon,
Rather than respond in detail to this and the other question you've
posted, I suggest you read up on threading in general. That way
hopefully you'll be able to come up with answers without us needing to
find out exactly what your situation is, etc. In general you are right, but....

1)
I already have read a lot to generally understand what threads are about.
I now hear you say... "but obviously not enough.." ;-)
You are right again! On the other side I could spend years on reading about
threads without ever reaching the point that I can say :"Now I know all, no
more need to bother others...."
Thereby I woul probably never get done with my application....
This leads us to :

2.)
In some cases its just faster to ask a specific question befor....-> 1.)
.... forgive me ;-)
I've got a threading tutorial at
http://www.pobox.com/~skeet/csharp/threads

Hopefully that'll provide a good starting point for you.

Thanks for the link, I promise to read that too....(somewhen;) ...
especially the chapter on "
Exclusive access - Monitor.Enter/Exit and the lock statement
Regards
Rainer
Jan 20 '06 #12
Hi Mark,

thanks four your help. I thing now I got it!
Looks like it would in my case also make sence to use Queue<T>. I will
read.....

Thanks
Rainer
Jan 20 '06 #13
Rainer Queck wrote:
Rather than respond in detail to this and the other question you've
posted, I suggest you read up on threading in general. That way
hopefully you'll be able to come up with answers without us needing to
find out exactly what your situation is, etc.

In general you are right, but....

1)
I already have read a lot to generally understand what threads are about.


Don't get me wrong - I wasn't trying to have a go at you. There was
nothing stupid about your question - it's just best answered at length,
in precise terms etc. Unfortunately, I don't have that much time right
now. Fortunately, I've had that much time in the past :)

Jon

Jan 20 '06 #14
Hi Jon,
Don't get me wrong likewise ;-)
Unfortunately, I don't have that much time right
now. I suffer the same problem. That's why "2.)" came into play.
Fortunately, I've had that much time in the past :)

Honestly! I am glad for that. I added your turorial to my KnowHow links, and
I hope to soon have the time to read it!

Regards
Rainer
Jan 20 '06 #15

"Rainer Queck" <Ra****@noemail.noemail> wrote in message
news:Ox*************@TK2MSFTNGP15.phx.gbl...
Hi Jon,
Rather than respond in detail to this and the other question you've
posted, I suggest you read up on threading in general. That way
hopefully you'll be able to come up with answers without us needing to
find out exactly what your situation is, etc.

In general you are right, but....

1)
I already have read a lot to generally understand what threads are about.
I now hear you say... "but obviously not enough.." ;-)
You are right again! On the other side I could spend years on reading
about threads without ever reaching the point that I can say :"Now I know
all, no more need to bother others...."
Thereby I woul probably never get done with my application....


No - I'm afraid you are wrong - you clearly do not understand sufficiently
what thread s are about.

Threads is one subject above all others where a little knowledge is
dangerous thing - it can appear that you have done it correctly, the
compiler will accept it and your tests all work and then you do something as
simple as move to a multi CPU system and it will fails....unpredicatably,
unrepeatably and with no useful diagnostics after 3 months on a customer
site.

John is right you should read up about it some more.
If you understood it at all you wouldn't ask this question as it is virtualy
the "Hello World" of thread programming.

Jan 20 '06 #16
Hello!
If you understood it at all you wouldn't ask this question as it is
virtualy the "Hello World" of thread programming.


Although the above statement may be right, I would still provide the OP a
few bonus points for posting the question here. Atleast it shows he's
interested in getting the right answer, and showing interest in doing
additional homework.

--
Venlig hilsen
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)
Jan 21 '06 #17
Anders Borum <an****@sphereworks.dk> wrote:
If you understood it at all you wouldn't ask this question as it is
virtualy the "Hello World" of thread programming.


Although the above statement may be right, I would still provide the OP a
few bonus points for posting the question here. Atleast it shows he's
interested in getting the right answer, and showing interest in doing
additional homework.


Indeed. Besides, the question of how threadsafe a collection can be is
clearly not a totally simple one: I personally believe there's little
point in have "synchronized" versions of collections, as you so rarely
only need to perform one operation at a time. However, clearly people
at Microsoft (and Sun) disagree.

--
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
Jan 21 '06 #18

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

Similar topics

4
by: Mikhail N. Kupchik | last post by:
Hi All. I have a question regarding C++ programming language standard. It is related to standard library, not to the core language. Is it portable to instantiate template class std::list<>...
4
by: matty.hall | last post by:
I have two classes: a base class (BaseClass) and a class deriving from it (DerivedClass). I have a List<DerivedClass> that for various reasons needs to be of that type, and not a List<BaseClass>....
0
by: Iron Moped | last post by:
I'm airing frustration here, but why does LinkedList<not support the same sort and search methods as List<>? I want a container that does not support random access, allows forward and reverse...
7
by: Andrew Robinson | last post by:
I have a method that needs to return either a Dictionary<k,vor a List<v> depending on input parameters and options to the method. 1. Is there any way to convert from a dictionary to a list...
56
by: Zytan | last post by:
Obviously you can't just use a simple for loop, since you may skip over elements. You could modify the loop counter each time an element is deleted. But, the loop ending condition must be...
45
by: Zytan | last post by:
This returns the following error: "Cannot modify the return value of 'System.Collections.Generic.List<MyStruct>.this' because it is not a variable" and I have no idea why! Do lists return copies...
2
by: csharpula csharp | last post by:
Hello, I would like to know what is better for data binding and serialization purposes ArrayList or List<? Thank you! *** Sent via Developersdex http://www.developersdex.com ***
11
by: paul.gibson | last post by:
A simple code example is easier than trying to describe the issue. I have: public class myClassA {
9
by: =?Utf-8?B?VHJlY2l1cw==?= | last post by:
Hello, Newsgroupians: I've an optimization question for you all really quick. I have a stream that I am reading some bytes. At times, the stream can contain a small amount of bytes such as 50...
4
by: =?Utf-8?B?SkI=?= | last post by:
Hello List<Tis said to be more powerful than ArrayLists but if you have something like this: List<intmylst = new List<>; myList.Add("Joe"); myList.Add(25); the list doesn't seem to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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
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
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...
1
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...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
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
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.