下面是我试图实现的目标:我正在用c(visualstudio)构建一个windows窗体格式的警报系统。我有一个带有datagrid视图的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;
}
}
2条答案
按热度按时间nfzehxib1#
您不必每次启动计时器时都订阅dowork事件。
您永远不会订阅runworkercompleted事件。
您应该将grids数据源分配给e.result,而不是不能由bgw更新的私有属性
不确定这将工作无论如何,你可能想看看调用。实际上,代码将抛出一个跨线程操作无效或目标调用异常。您需要在网格控件上使用invoke。
rjzwgtxy2#
我将对您的代码进行一些更改:
使用
Timer
从windows窗体工具箱而不是System.Threading.Timer
(它的设计是为了在windows窗体中更好地工作)。将其拖到窗体上,然后将事件处理程序附加到其Tick
方法来获取定期更新。连接
BackgroundWorker
事件处理程序只有一次。将backgroundworker组件从设计器工具箱拖到窗体上,以便为您管理其生存期;不要使用
static
现场。使用
using
对账单MySqlConnection
清理它使用的资源。使用示例方法(不是
static
)因此,您可以引用Alerts
班级。举个例子: