views:

129

answers:

2

Hello all

I want to update a single datarow in a datatable using multiple threads. Is this actually possible?

I've written the following code implementing a simple multi-threading to update a single datarow. I get different results each time. Why is it so?

public partial class Form1 : Form
{
    private static DataTable dtMain;
    private static string threadMsg = string.Empty;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Thread[] thArr = new Thread[5];
        dtMain = new DataTable();
        dtMain.Columns.Add("SNo");
        DataRow dRow;
        dRow = dtMain.NewRow();
        dRow["SNo"] = 5;
        dtMain.Rows.Add(dRow);
        dtMain.AcceptChanges();
        ThreadStart ts = new ThreadStart(delegate { dtUpdate(); });
        thArr[0] = new Thread(ts);
        thArr[1] = new Thread(ts);
        thArr[2] = new Thread(ts);
        thArr[3] = new Thread(ts);
        thArr[4] = new Thread(ts);

        thArr[0].Start();
        thArr[1].Start();
        thArr[2].Start();
        thArr[3].Start();
        thArr[4].Start();

        while (!WaitTillAllThreadsStopped(thArr))
        {
            Thread.Sleep(500);
        }

        foreach (Thread thread in thArr)
        {
            if (thread != null && thread.IsAlive)
            {
                thread.Abort();
            }
        }
        dgvMain.DataSource = dtMain;

    }

    private void dtUpdate()
    {
        for (int i = 0; i < 1000; i++)
        {
            try
            {
                dtMain.Rows[0][0] = Convert.ToInt32(dtMain.Rows[0][0]) + 1;
                dtMain.AcceptChanges();
            }
            catch
            {
                continue;
            }
        }
    }

    private bool WaitTillAllThreadsStopped(Thread[] threads)
    {
        foreach (Thread thread in threads)
        {
            if (thread != null && thread.ThreadState == ThreadState.Running)
            {
                return false;
            }
        }
        return true;
    }


}

Any thoughts on this?

Thank you

NLV

+2  A: 

According to MSDN:

This type is safe for multithreaded read operations. You must synchronize any write operations.

So since you are updating DataRow and DataTable objects you will need to use some form of synchronization to guarantee your code is thread safe.

By the way, you should also never call Thread.Sleep or do a busy loop in your UI thread. Otherwise the UI will be completely unresponsive until all threads have finished executing. Instead you should have some kind of progress bar (or just a spinner) displayed on your UI, which is optionally updated by events from your threads. The BackgroundWorker class is specifically designed to make this job easier for you, so you may want to consider using it.

Justin Ethier
A: 

Unless the documentation for the type or member specifies otherwise:

  • Static members are thread safe.
  • Instance members are not thread safe.
Richard