首页 > 解决方案 > c# 使用 MySQL 数据库中的后台工作人员每 5 秒更新一次数据网格视图

问题描述

这是我想要实现的目标:我正在 c# (visual studio) 中以 Windows 窗体格式构建警报系统。我有一个带有数据网格视图的 Windows 窗体,需要每 5 秒从 MySQL 数据库获取信息。我正在使用 System.Threading.Timer 和后台工作人员。我为此搜索了所有线程,但似乎没有任何效果。计时器正在工作,因为我每 5 秒出现一次线程错误,所以问题一定出在后台工作代码中。这是代码:

public partial class Alerts : Form
{
    private System.Threading.Timer _timerThread;
    private int _period = 5000;
    static BackgroundWorker bgw = new BackgroundWorker();

    public Alerts()
    {
        InitializeComponent();

        _timerThread = new System.Threading.Timer((o) =>
        {
            // Stop the timer;
            _timerThread.Change(-1, -1);


            bgw.DoWork += bgw_DoWork;
            bgw.RunWorkerAsync();


            // start timer again (BeginTime, Interval)
            _timerThread.Change(_period, _period);
        }, null, 0, _period);


    }

    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        string constring = "datasource=localhost;port=3306;username=root;password=*******";
        MySqlConnection conDataBase = new MySqlConnection(constring);
        MySqlCommand cmdDataBase = new MySqlCommand(" select * from shopmanager.alerts ;", conDataBase);

        try
        {
            conDataBase.Open();
            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);
        }
        conDataBase.Close();
    }

    static void bgw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
    {
        // I think this is where I should be able to update the datagridview but i'm not sure how.
    }
}

我完全迷路了。请帮忙

我现在尝试了这段代码,但它无法识别 DataGridView1。我究竟做错了什么?

 public partial class Alerts : Form
{
    private System.Threading.Timer _timerThread;
    private int _period = 5000;
    static BackgroundWorker bgw = new BackgroundWorker();
    private static object dbdataset;

    public Alerts()
    {
        InitializeComponent();

        _timerThread = new System.Threading.Timer((o) =>
        {
            // Stop the timer;
            _timerThread.Change(-1, -1);


            // Calls UpdateAlerts() that updates a datagridview with the mysql data
            bgw.DoWork += bgw_DoWork;
            bgw.RunWorkerAsync();


            // start timer again (BeginTime, Interval)
            _timerThread.Change(_period, _period);
        }, null, 0, _period);


    }

    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        string constring = "datasource=localhost;port=3306;username=root;password=******";
        MySqlConnection conDataBase = new MySqlConnection(constring);
        MySqlCommand cmdDataBase = new MySqlCommand(" select * from shopmanager.alerts ;", conDataBase);


        try
        {
            conDataBase.Open();
            MySqlDataAdapter sda = new MySqlDataAdapter();
            sda.SelectCommand = cmdDataBase;
            DataTable dbdataset = new DataTable();
            sda.Fill(dbdataset);
            BindingSource bsource = new BindingSource();

            bsource.DataSource = dbdataset;
            sda.Update(dbdataset);
            e.Result = dbdataset;

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        conDataBase.Close();
    }

    static void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        DataGridView1.DataSource = dbdataset;
    }
}

标签: c#mysql

解决方案


我将对您的代码进行许多更改:

  • 使用TimerWindows 窗体工具箱中的而不是System.Threading.Timer(它旨在更好地在 Windows 窗体中工作)。将其拖到表单上,然后将事件处理程序附加到其Tick方法以获取定期更新。
  • 仅附加BackgroundWorker一次事件处理程序。
  • 将 BackgroundWorker 组件从设计器工具箱拖到表单上,以便为您管理其生命周期;不要使用字段static
  • 使用usingwith 语句MySqlConnection来清理它使用的资源。
  • 使用实例方法(不是static),以便您可以引用Alerts类中的属性/字段。

这是一个例子:

public partial class Alerts : Form
{
    public Alerts()
    {
        InitializeComponent();

        // set up BackgroundWorker once
        backgroundWorker1.DoWork += OnDoWork;
        backgroundWorker1.RunWorkerCompleted += OnRunWorkerCompleted;

        // set the timer and start it running
        timer1.Interval = 5000;
        timer1.Start();
        timer1.Tick += (o, e) => backgroundWorker1.RunWorkerAsync();
    }

    // This method will run in the background every five seconds. It can't
    // access parts of the form since it is on a background thread.
    private void OnDoWork(object sender, DoWorkEventArgs e)
    {
        using (MySqlConnection conDataBase = new MySqlConnection(connectionString))
        using (MySqlCommand cmdDataBase = new MySqlCommand(" select * from shopmanager.alerts;", conDataBase))
        {
            conDataBase.Open();
            MySqlDataAdapter sda = new MySqlDataAdapter { SelectCommand = cmdDataBase };
            DataTable dbdataset = new DataTable();
            sda.Fill(dbdataset);

            // return the results to the main form thread through this property
            e.Result = dbdataset;
        }
    }

    void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // This will run on the main form thread when the background work is
        // done; it connects the results to the data grid.
        dataGridView1.DataSource = e.Result;
    }
}

推荐阅读