1

我想使用多个线程更新数据表中的单个数据行。这真的可能吗?

我编写了以下代码,实现了一个简单的多线程来更新单个数据行。每次我得到不同的结果。为什么会这样?

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;
    }


}

对此有什么想法吗?

谢谢

NLV

4

2 回答 2

3

根据MSDN

这种类型对于多线程读取操作是安全的。您必须同步任何写入操作。

因此,由于您正在更新对象DataRow,因此DataTable您需要使用某种形式的同步来保证您的代码是线程安全的。

顺便说一句,你也不应该Thread.Sleep在你的 UI 线程中调用或做一个繁忙的循环。否则,UI 将完全无响应,直到所有线程都完成执行。相反,您应该在您的 UI 上显示某种进度条(或只是一个微调器),它可以由线程中的事件选择性地更新。BackgroundWorker类专门设计用于使您更轻松地完成这项工作,因此您可能需要考虑使用它。

于 2010-04-13T11:37:12.263 回答
0

除非类型或成员的文档另有说明:

  • 静态成员是线程安全的。
  • 实例成员不是线程安全的。
于 2010-04-13T11:39:29.693 回答