问题描述
初学C#有个用C#做接口的任务需要实时读取MYSQL数据库中某表字段值来触发操作查到如果是SQL2005以上可以用SqlDependency启用Servicebroker来做,但是mysql有什么办法呢我现在想实在不行就用定时器了,但是对C#结构不是很了解,好像不能定义全局对象,那么我如果在定时器的话,要在哪里定义,MySqlConnection,MySqlCommand,MySqlDataReader,如果在timer1_Tick里面,那么我timer控件设置的100毫秒,那是不是每100毫秒都要执行创建和销毁这三个对象啊!我现在的代码如下,请大神帮忙privatevoidtimer1_Tick(objectsender,EventArgse){stringserver="127.0.0.1";stringdatabase="chenkuserdb5";stringname="root";stringpassword="";stringconnectionString="DATABASE="+database+";"+"server="+server+";"+"UserId="+name+";"+"PASSWORD="+password+";pooling=false;CharSet=utf8;port=3308";MySqlConnectionconnection=newMySqlConnection(connectionString);stringmysqlStr="SELECTidfromtblattachment";MySqlCommandmySqlCmd=connection.CreateCommand();mySqlCmd.Connection.Open();mySqlCmd.CommandType=CommandType.Text;mySqlCmd.CommandText=mysqlStr;MySqlDataReadermySqlReader;mySqlReader=mySqlCmd.ExecuteReader();while(mySqlReader.Read()){textBox1.Text=mySqlReader["id"].ToString();}connection.Close();connection.Dispose();}
解决方案
解决方案二:
当数据库中某个值改变了,你就要执行C#代码,去执行一些业务逻辑?这个设计未免太不合理了吧。显然就算要执行业务逻辑,要么用触发器去执行sql语句搞。或者对数据库执行插入和更新时,调用下你开放的接口函数啊。如果实在要这么干,通过轮询数据库来判断值改变的话,connection,command的对象,定义在方法之外,作为类的私有变量好了。不要每100ms就创建-销毁的。
解决方案三:
一般来说Dependency功能都是通过定时轮询来实现的……至于销毁……Close就可以了,Dispose不需要,这个由数据库连接池来管理,可以实现复用
解决方案四:
引用1楼txfast的回复:
当数据库中某个值改变了,你就要执行C#代码,去执行一些业务逻辑?这个设计未免太不合理了吧。显然就算要执行业务逻辑,要么用触发器去执行sql语句搞。或者对数据库执行插入和更新时,调用下你开放的接口函数啊。如果实在要这么干,通过轮询数据库来判断值改变的话,connection,command的对象,定义在方法之外,作为类的私有变量好了。不要每100ms就创建-销毁的。
我是要写一个跟别的程序的接口,另我一上程序不提供接口,我只能通判断数据库值来触发操作了。定义放在方法外,我就是没整明白,哪些放在方法外,哪些放在方法内能给个具体的写法么?publicForm1(){InitializeComponent();mySqlCmd.Connection.Open();mySqlCmd.CommandType=CommandType.Text;mySqlCmd.CommandText=mysqlStr;mySqlReader=mySqlCmd.ExecuteReader();}
我把这些放到初始化里了Tick里只留了mySqlReader.Read(),但是好像他读的只是初始化时表里面的数据,此时如果数据库表有变化,read()出来的不是新数据,还是老的。如果把mySqlReader=mySqlCmd.ExecuteReader();放到Tick里面又会报错,提示要先关闭连接再创建。privatevoidtimer1_Tick(objectsender,EventArgse){while(mySqlReader.Read()){textBox1.Text=mySqlReader["id"].ToString();}}
解决方案五:
自已UP一下!
解决方案六:
C#本身是不支持连接MySQL的,不知道你是通过ODBC还是MySQL客户端进行操作的如果是前者,那么安装MySQLODBC后,就与C#提供的数据库操作没什么两样了(有的只是SQL指令上的差异)如果是后者,则应采用长连接方式,以减少连接开销查了一下MySqlConnection族好像是封装了MySQL客户端。具体用法不是很清楚不过MySqlConnectionconnection=newMySqlConnection(connectionString);应放在方法外面connection.Close();只是关闭连接,并不是销毁对象。再open就又连上了
解决方案七:
1、不建议用timer;2、如果不停的读取这个数据库,尽量让这个DB变成本地的;3、如果数据库是别人的软件写入的,直接优化数据库并解决读取刷新问题才是问题的突破口;4、如果别人的软件写数据库的时候是有规律可循的,请按这个规律来读取数据库即可;5、如果写入数据库无规律,或者是完全实时的,那么不建议实时读取,因为可能会有死锁或者冲突;6、其他的问题需要具体分析你的状况才能确定解决方案。
解决方案八:
MySQL也支持计划任务吧,建议将业务逻辑写在存储过程中,每分钟MySQL自动执行。如果无法在存储过程中完成,可通过C#程序连接数据库完成,当然执行间隔可以放宽至5分钟、10分钟。
解决方案九:
引用3楼qiwen1530的回复:
Quote: 引用1楼txfast的回复:
当数据库中某个值改变了,你就要执行C#代码,去执行一些业务逻辑?这个设计未免太不合理了吧。显然就算要执行业务逻辑,要么用触发器去执行sql语句搞。或者对数据库执行插入和更新时,调用下你开放的接口函数啊。如果实在要这么干,通过轮询数据库来判断值改变的话,connection,command的对象,定义在方法之外,作为类的私有变量好了。不要每100ms就创建-销毁的。我是要写一个跟别的程序的接口,另我一上程序不提供接口,我只能通判断数据库值来触发操作了。定义放在方法外,我就是没整明白,哪些放在方法外,哪些放在方法内能给个具体的写法么?publicForm1(){InitializeComponent();mySqlCmd.Connection.Open();mySqlCmd.CommandType=CommandType.Text;mySqlCmd.CommandText=mysqlStr;mySqlReader=mySqlCmd.ExecuteReader();}
我把这些放到初始化里了Tick里只留了mySqlReader.Read(),但是好像他读的只是初始化时表里面的数据,此时如果数据库表有变化,read()出来的不是新数据,还是老的。如果把mySqlReader=mySqlCmd.ExecuteReader();放到Tick里面又会报错,提示要先关闭连接再创建。privatevoidtimer1_Tick(objectsender,EventArgse){while(mySqlReader.Read()){textBox1.Text=mySqlReader["id"].ToString();}}
如果一个对象需要反复销毁,创建的话,就放循环体外面。