2014-05-08 37 views
0

我尝试使用计时器每秒连接并显示数据库到DatagridView1。 Im在C#中是新的,所以我对线程系统感到困惑。我尝试从定时器中调用munculkantabel(),并且始终返回该线程操作无效:从除创建线程之外的线程访问的控制。那么如何解决这个问题?如何线程安全调用DataGridView

public void buattimer() 
    { 
     System.Timers.Timer aTimer = new System.Timers.Timer(); 
     aTimer.Elapsed += new ElapsedEventHandler(backgroundWorker1_DoWork); 
     aTimer.Interval = 1000; 
     aTimer.Enabled = true; 
    } 

    public void backgroundWorker1_DoWork(object source, ElapsedEventArgs e) 
    { 
     Thread thh = new Thread(munculkantabel); 
     thh.Start(); 
    } 


string constring = "datasource=localhost;port=3306;username=root;password=;convert zero datetime=True"; 
    public void munculkantabel() 
    { 
     MySqlConnection conDataBase = new MySqlConnection(constring); 
     MySqlCommand cmdDataBase = new MySqlCommand(" select * from konsentrasi.okedeh ;", conDataBase); 
     try 
     { 
      MySqlDataAdapter sda = new MySqlDataAdapter(); 
      sda.SelectCommand = cmdDataBase; 
      DataTable dbdataset = new DataTable(); 
      sda.Fill(dbdataset); 
      BindingSource bSource = new BindingSource(); 

      bSource.DataSource = dbdataset; 
      dataGridView1.DataSource = bSource; 
      sda.Update(dbdataset); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

回答

0

GUI组件绑定到运行GUI消息泵的线程。

从任何其他线程的直接访问是未定义行为的道路(有些事情可能似乎工作,如果你是运气,其他所有...)。

相反,从工作线程(例如,响应于该计时器事件)需要使用GUI控制的BeginInvoke(这是一个例外到前一段落)方法来在GUI上执行任何操作线。

在代码中,替换

bSource.DataSource = dbdataset; 
dataGridView1.DataSource = bSource; 
sda.Update(dbdataset); 

有:

dataGridView1.BeginInvoke(() => { 
    bSource.DataSource = dbdataset; 
    dataGridView1.DataSource = bSource; 
    sda.Update(dbdataset); 
}); 

当然,这依赖于对数据的更改网格也多了GUI线程上同样运行任何代码,在已知上述代码已完成的方式。在你的情况下,你并没有直接受到这个影响,因为你没有清理数据库连接等。(答案:清理GUI线程上的连接等,或者至少在上述之后从GUI线程启动的任务中码)。

还要注意,BeginInvoke也是例外,“如果你叫BeginABC必须调用EndABC执行任何清除”的规则:在这种情况下EndInvoke不需要(并记录为此类)。

+0

我尝试更换,但它说错误1不能将lambda表达式转换为键入'System.Delegate',因为它不是委托类型。怎么了? – tzudin

+0

@tzudin尝试转换为'Delegate'(对于委托类型,编译器无法看到'System.Delegate'和'System.Action'类型是兼容的)类型。 – Richard

0

所有您需要做的就是使用正确的计时器WinFormsWPF

+0

我使用timertick,这是工作。谢谢 – tzudin