fraXis
fraXis

Reputation: 3221

C# DataTable forgetting it's column(s) after extended use

I am using a DataTable in my .Net 3.5 application to store 1 column, with some records that contain a filename.

Here is my code on how and where I initialize my DataTable:

public partial class MainForm : Form
{
    DataTable memTable_CurrentTransfers = new DataTable();


private void MainForm_Load(object sender, EventArgs e)
{
    memTable_CurrentTransfers.Columns.Add("fileName", typeof (string));


Here is how I add the filename to my DataTable in another method of my application:

memTable_CurrentTransfers.Rows.Add(fileName);


Every 30 minutes, I launch a thread that executes this code:

public void CheckUploads()
{
   DataView view2 = memTable_CurrentTransfers.DefaultView;

   for (int i = 0; i < view2.Count; i++)
   {
     string tmpString = view2[i][0].ToString();


Everything works great, but after after my application is running for a while, my users are starting to get this error in the CheckUploads() method

The given key was not present in the dictionary. at System.ThrowHelper.ThrowKeyNotFoundException() at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at System.Data.DataView.get_Item(Int32 recordIndex)


I think that my column is disappearing from my DataTable.

Can please anyone tell me why this is happening and how I can stop this from occurring? Is there another way I should be initializing my DataTable so it is available from all methods inside of my application?

Upvotes: 1

Views: 331

Answers (1)

to StackOverflow
to StackOverflow

Reputation: 124746

For a start, a DataTable is not thread-safe, and the code you posted doesn't include any synchronisation.

Can you elaborate on "doesn't include any Synchronization"?

You say you have multiple threads accessing the DataTable: your CheckUploads method is on a background thread, and, presumably, there is code to add (and possibly remove) rows in your main thread.

I'd recommend you design the application such that no synchronization is required. For example, pass a clone of the main DataTable to your background thread, so that there is never more than one thread accessing the same instance.

I think that my column is disappearing from my DataTable.

I don't see any evidence of that: the stack trace seems to show that it's failing to find a row ( System.Data.DataView.get_Item(Int32 recordIndex)) not a column.

From ebyrob's comment:

lock(memTable_CurrentTransfers) { memTable_CurrentTransfers.Rows.Add(filename) } and similar around every other access to memTable_CurrentTransfers.

You would also need to use the same lock round any access to the DataView. Though it's easy to get synchronization wrong, so I stand by the recommendation to design your app so that synchronization isn't needed.

Upvotes: 1

Related Questions