473,651 Members | 2,533 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

DataTable weirdness

Hi

I have written a .NET service that uses two DataTables to store runtime
data. One column in one table is periodically updated (every 10 seconds, and
upon user request), another is updated upon user action.

The code works fine most of the time. I've had it running on a W2K server
for over half a year with little issues. Though when running the same code
on a W2K3 server, I regularly get IndexOutofRange exceptions at random
intervals (if I start the service it can run fine for two weeks, or it can
start throwing exceptions right away, and the problem might go away after a
while). Here's an example of such an exception:

03:59:03 Monitor.run for vm Cisco1 catched an exception: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index source mscorlib stacktrace at
System.Collecti ons.ArrayList.R emoveAt(Int32 index)
at System.Data.Rec ordManager.NewR ecordBase()
at System.Data.Dat aTable.NewRecor d(Int32 sourceRecord)
at System.Data.Dat aRow.BeginEdit( )
at System.Data.Dat aRow.set_Item(D ataColumn column, Object value)
at System.Data.Dat aRow.set_Item(S tring columnName, Object value)
at VRSService.Moni tor.run() in c:\documents and settings\sste\m y
documents\visua l studio projects\vrsser vice\vmmonitor. cs:line 787

The line of code throwing the exception is as follows:

myRow["timestamp"] = timestamp; // timestamp = 64bit integer representing
DateTime.Ticks

Now, in absence of any changes to the table and row in question (I have the
DataTable in one class, and send the appropriate row as constructor
parameter to the class that does the updating). The rows in the datatable
are never deleted/replaced, no new rows are ever inserted after the
application startup, and the first column (unique) is never updated. Also,
only updating the timestamp column (the most regular of any updates because
it happens every 10 seconds, whereas the rest is user triggered and a lot
less frequent) throws that error. During the 24h from Saturday midnight to
Sunday midnight (where no user ever connected), I got this error 5 times,
not for all rows, but for some rows more than once.

Since I'm not touching the table, and since the code can fail without any
apparent reason at any time, I'm getting the lingering suspicion that the
implementation of cell updates (the stacktrace makes me think the entire row
is removed and a new one added), can have a problem. I have never
experienced this problem when running the application on my development
boxes (WinXP), it might have happened once or twice in a half year period on
W2K server but it happens quite frequently on W2K3, which afaik is the only
one to not use the standard .NET framework.

Has anyone else ever experienced something like that? I have since written
my code to catch those exceptions (initially they'd be thrown and kill the
thread to do the update every 10 seconds, which eventually would lead to a
situation where the service had to be restarted), and funny enough it seems
that now once thrown, as the thread runs for the next time (10 seconds
later), things are okay again. Still, I shouldn't get those exceptions as
I'm not referencing any column in the row that is non existing.

Regards
Stephan
Nov 16 '05 #1
6 4229
Stephan,

Sounds like it might be a threading issue. Are you locking the
DataTable that owns myRow before doing the update?

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/
Nov 16 '05 #2
Chris

Ahh, now it all comes together. I must've misread the class documentation
because I thought write operations were also thread safe, not only reads.
Hence I'm not locking the datatable prior to the update. What is the most
efficient way to lock and unlock a table that still permits synchronous
operations (so no resorting to using delegates to get a reply from the write
operation) so that my write operations don't interfere with each other?
Regards
Stephan
Nov 16 '05 #3
"Stephan Steiner" <st*****@isuiss e.com> wrote in
news:eP******** ******@TK2MSFTN GP09.phx.gbl:
Chris

Ahh, now it all comes together. I must've misread the class
documentation because I thought write operations were also
thread safe, not only reads. Hence I'm not locking the datatable
prior to the update. What is the most efficient way to lock and
unlock a table that still permits synchronous operations (so no
resorting to using delegates to get a reply from the write
operation) so that my write operations don't interfere with each
other?


Stephan,

If the method updating the data structure is an instance method, then
locking "this" is what is usually done:

lock(this)
{
...
myRow["timestamp"] = timestamp;
...
}

If the method is a static method, there will be no "this" to lock.
In that case, the class needs to create an object to lock on:

public class MyClass
{
private static readonly object countLock = new object();

public static void UpdateMyRow()
{
lock(countLock)
{
...
myRow["timestamp"] = timestamp;
...
}
}
}
MVP Jon Skeet has written an excellent article about threading in C#:

http://www.yoda.arachsys.com/csharp/threads/

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/
Nov 16 '05 #4
Chris

Thanks for the link to the article (I've seen it on other occasions but
never read the entire thing).

I'm currently implementing locks into my software, but I'm wondering:

If I iterate through all the elements of a table in thread A, and at the
same time I write to a cell in the database from a thread B (the entire
write operation is encapsulated in a lock statement). The doc says DB reads
are thread safe. So, am I correct assuming that the lock in thread B will
block until the iterator is no longer used?

Come to think of it I've experienced similar conditions previously: while
iterating through the rows in a table, I find that I need to delete a row. I
can delete the row just fine inside the iteration but when I try to get the
next element via the foreach iterator, I get an exception because the
collection of lines has changed. So I ended up storing which lines I have to
delete, then after going through all lines, I deleted the lines marked for
deletion. In this case, what would an attempt to delete a record directly
within the iteration (using the lock statement) yield? Will the code in the
lock statement just be skipped because I'm currently interating through the
table rows?

Regards
Stephan

If the method updating the data structure is an instance method, then
locking "this" is what is usually done:

lock(this)
{
...
myRow["timestamp"] = timestamp;
...
}

If the method is a static method, there will be no "this" to lock.
In that case, the class needs to create an object to lock on:

public class MyClass
{
private static readonly object countLock = new object();

public static void UpdateMyRow()
{
lock(countLock)
{
...
myRow["timestamp"] = timestamp;
...
}
}
}
MVP Jon Skeet has written an excellent article about threading in C#:

http://www.yoda.arachsys.com/csharp/threads/

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/

Nov 16 '05 #5
"Stephan Steiner" <st*****@isuiss e.com> wrote in
news:ux******** ******@TK2MSFTN GP09.phx.gbl:
Chris

Thanks for the link to the article (I've seen it on other
occasions but never read the entire thing).

I'm currently implementing locks into my software, but I'm
wondering:

If I iterate through all the elements of a table in thread A,
and at the same time I write to a cell in the database from a
thread B (the entire write operation is encapsulated in a lock
statement). The doc says DB reads are thread safe. So, am I
correct assuming that the lock in thread B will block until the
iterator is no longer used?
Stephan,

No. The lock on thread B will block other threads from entering
thread B's locked section until that section is finished executing.
Thread B's lock will not prevent other threads from executing if they
are not trying to enter that same locked section.

In other words, thread A's read operations will run concurrently with
thread B's write operations. This happens because thread A is not
trying to enter thread B's locked section.

It sounds like you might want serialized access to a particular data
structure (atomicity):

http://www.yoda.arachsys.com/csharp/...latility.shtml

To implement atomicity on a collection like an ArrayList, you can
have all read and write operations lock on the same object reference.

Below is a short program that demonstrates "atomicized " multiple read
and write operations on an ArrayList. Both operations lock the
ArrayList to achieve this. To see the non-atomic behavior, simply
uncomment the DoReads() method's lock statement.

using System;
using System.Collecti ons;
using System.Threadin g;

namespace Example
{
public class Test
{
private ArrayList a = new ArrayList();

private void DoWrites()
{
int counter = 0;

while (true)
{
lock (a)
{
if (a.Count >= 15)
a.Clear();

Console.WriteLi ne("===== BEGIN WRITING =====");
for (int i = 0; i < 5; i++)
{
a.Add(++counter );
Console.WriteLi ne("Writing: {0}", counter);
Thread.Sleep(10 0);
}
Console.WriteLi ne("===== END WRITING =====");
}
}
}

private void DoReads()
{
while (true)
{
// Comment out this lock statement to see
// non-atomic behavior.
lock (a)
{
Console.WriteLi ne("===== BEGIN READING =====");
for (int i = 0; i < a.Count; i++)
{
Console.WriteLi ne("Reading: {0}", (int) a[i]);
Thread.Sleep(10 0);
}
Console.WriteLi ne("===== END READING =====");
}
}
}

public void DoReadsAndWrite s()
{
ThreadStart doWrites = new ThreadStart(DoW rites);
Thread doWritesThread = new Thread(doWrites );
doWritesThread. Start();

// Start the thread.
Thread.Sleep(0) ;

ThreadStart doReads = new ThreadStart(DoR eads);
Thread doReadsThread = new Thread(doReads) ;
doReadsThread.S tart();

// Start the thread.
Thread.Sleep(0) ;

// Use Ctrl-C to end the program.
}

public static void Main(string[] args)
{
new Test().DoReadsA ndWrites();
}
}
}
Come to think of it I've experienced similar conditions
previously: while iterating through the rows in a table, I find
that I need to delete a row. I can delete the row just fine
inside the iteration but when I try to get the next element via
the foreach iterator, I get an exception because the collection
of lines has changed. So I ended up storing which lines I have
to delete, then after going through all lines, I deleted the
lines marked for deletion. In this case, what would an attempt
to delete a record directly within the iteration (using the lock
statement) yield? Will the code in the lock statement just be
skipped because I'm currently interating through the table rows?


I don't think a lock would help in that case. The problem arises
within any kind of loop which iterates over a collection of data and
deletes one or more elements from that collection. It has nothing to
do with locking, but with the repositioning of the elements of the
collection when an element is removed.

When an element is removed, the behavior for most ordered collections
is to move the remaining elements "up" one level to fill the gap
created by the removal. For example, if a collection of numbers
consists of:

1
2
3
4
5

and element 3 is removed, the collection will now have a gap between
2 and 4:

1
2

4
5

The underlying collection will typically remove the gap by moving the
4 and 5 elements "up" to fill the gap:

1
2
4
5

This causes problems for any loop that started with the assumption
that the collection held 5 elements. When the loop reaches its fifth
iteration, it will find no element to retrieve, and it will throw an
exception.

The solution is usually to simply reverse the loop so it iterates
over the collection from the end to the beginning. This won't work
with a foreach loop, because those loops always iterate from the
beginning of the collection to the end. But other kinds of looping
constructs, including for and while, can be reversed to iterate over
the collection from the end to the beginning. In these cases,
deleting elements from the collection will not cause problems.

For example, a for loop constructed like this:

for (int i = 0; i < myDataView.Coun t; i++)

can be reversed like this:

for (int i = myDataView.Coun t - 1; i >= 0; i--)

--
Hope this helps.

Chris.
-------------
C.R. Timmons Consulting, Inc.
http://www.crtimmonsinc.com/
Nov 16 '05 #6
Chris

Below is a short program that demonstrates "atomicized " multiple read
and write operations on an ArrayList. Both operations lock the
ArrayList to achieve this. To see the non-atomic behavior, simply
uncomment the DoReads() method's lock statement.
Thanks for the example. I went to my program and did something similar
(there's quite a few instances where I potentially could run into problems..
most of them have never ocurred but I figured better safe than sorry and
make this thing work flawlessly no matter what).
Hope this helps.


Yes it helped a lot. Thanks again

Regards
Stephan
Nov 16 '05 #7

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

Similar topics

15
2170
by: Corne' Cornelius | last post by:
Hi, I'm experiencing some weirdness in a program, when subtracting 2 (double)'s which should result in 0, but instead it returns -1.11022e-16. It looks to me that changing the double x_step decleration to unsigned type, might help, but the compiler complains when i try that. Any ideas ? #include <iostream>
1
2420
by: (Pete Cresswell) | last post by:
TabControl on the right side of a form with two tabs: Tab #1 contains two subforms that show some dynamic query results. Tab #2 contains a ListView that gets dynamically populated as the user navigates a TreeView on the left side of the form. The first time I load the ListView, if the tab containing it is not selected (i.e. the ListView is not visible) the screen draws the ListView's contents in the upper left portion of the form -...
0
1553
by: Bruce B | last post by:
Hi group, I'm experiencing some extreme weirdness over the last week with IIS related to it's Mappings and how .NET is behaving. I can't explain the behavior as it seems very random. Our app has about 50 file extensions that we map in IIS and handle in our HTTPHandler to catch the reference and then lookup the correct content from a database. In addition, we do some magic in a HTTPModule to rewrite paths for file types we don't...
1
1272
by: VB Programmer | last post by:
My development machine has been working perfectly, writing ASP.NET apps, etc... I just went to open a project and it said: "Visual Studio .NET has detected that the specified web server is not running ASP.NET version 1.1. You will be unable to run ASP.NET Web apps or services." I reran "aspnet_regiis -i " but it still gives me the error. Here's the output:
5
2268
by: Phil Weber | last post by:
I'm attempting to debug an ASP.NET Web application in VS.NET 2003. I'm running the app and the debugger on my local machine (Windows XP Professional). I am logged in as a local administrator. In order to rule out permissions issues, I have set the processModel username to "SYSTEM" in my machine.config. Here's my problem: The ASP.NET app (compiled in debug mode) works correctly, whether I start it with debugging (F5) or without (Ctrl+F5)....
5
1695
by: David Thielen | last post by:
Hi; I am creating png files in my ASP .NET app. When I am running under Windows 2003/IIS 6, the file is not given the security permissions it should have. It does not have any permission for several users that the directory it is in has, including IUSR_JASMINE (my system is named jasmine). Here is the weird part. In my aps .net code I have the following: String jname = Request.PhysicalApplicationPath + "images\\java_" + fileNum +...
1
1653
by: rhino | last post by:
I've got some positioning problems that I can't figure out. Can anyone help? My website was working fine in IE7 and the current releases of Firefox and Opera so I had a look at it in IE6 and found that it was messed up. The major problem is that in IE6 the index, which was supposed to be on the left, was on the right, OVERLAYING the content on its right side. I finally resolved that problem in a way that allows both versions of IE6 and...
26
2263
by: Prisoner at War | last post by:
Hi, All: I have a JavaScript search engine that always causes MSIE 7 to do a top-of-page security "warning" (that top-of-page-bar, and not an "alert" )...but other websites' JavaScripts do not trigger that...what's going on? When I visit other JavaScript sites there's no warning and the scripts work fine, but mine (it's still under construction, offline) occasions that warning and I have to manually allow MSIE to run JavaScript every...
2
2367
by: JYA | last post by:
Hi. I was writing an xmltv parser using python when I faced some weirdness that I couldn't explain. What I'm doing, is read an xml file, create another dom object and copy the element from one to the other. At no time do I ever modify the original dom object, yet it gets modified.
0
8275
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,...
0
8795
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8576
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5609
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4143
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
4281
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2696
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 we have to send another system
1
1906
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1585
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.