2010-04-13 6 views
1

Я хочу обновить один datarow в datatable, используя несколько потоков. Возможно ли это?Безопасна ли DataRow? Как обновить один datarow в datatable, используя несколько потоков? - .net 2.0

Я написал следующий код, реализующий простую многопоточность для обновления одного datarow. Я получаю разные результаты каждый раз. Почему это так?

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

ответ

2

По MSDN:

Этот тип является безопасным для многопоточных операций чтения. Вы должны синхронизировать любые операции записи.

Так, так как вы обновляете DataRow и DataTable объекты, которые нужно будет использовать некоторые формы синхронизации, чтобы гарантировать ваш код поточно.

Кстати, вы также никогда не должны звонить Thread.Sleep или выполнять цикл занятости в потоке пользовательского интерфейса. В противном случае пользовательский интерфейс будет полностью не отвечать на запросы до тех пор, пока все потоки не закончатся. Вместо этого у вас должен быть какой-то индикатор выполнения (или просто счетчик), отображаемый в вашем пользовательском интерфейсе, который необязательно обновляется событиями из ваших потоков. Класс BackgroundWorker специально разработан для упрощения этой работы, поэтому вы можете захотеть использовать его.

1

Если в документации по типу или члену не указано иное:

  • Статические члены поточно.
  • Элементы экземпляра не нить безопасная.