[ Team LiB ] |
Recipe 9.14 Refreshing a DataSet Automatically Using Extended PropertiesProblemYou need to automatically refresh a DataSet periodically. SolutionUse extended properties and a timer. The sample code contains two event handlers and one method:
The C# code is shown in Example 9-17. Example 9-17. File: AutomaticRefreshDataSetForm.cs// Namespaces, variables, and constants using System; using System.Configuration; using System.Threading; using System.Data; using System.Data.SqlClient; private const String CATEGORIES_TABLE = "Categories"; private const int DATAREFRESH_SECONDS = 15; private const int DATASETCHECKREFRESHINTERVAL_MS = 1000; private DataTable dt, dtRefresh; private SqlDataAdapter da, daRefresh; private System.Threading.Timer timer; // .. private void AutomaticRefreshDataSetForm_Load(object sender, System.EventArgs e) { String sqlText = "SELECT CategoryID, CategoryName, Description FROM Categories"; // Fill the categories table for editing. da = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_ConnectString"]); SqlCommandBuilder cd = new SqlCommandBuilder(da); dt = new DataTable(CATEGORIES_TABLE); da.FillSchema(dt, SchemaType.Source); da.Fill(dt); // Bind the default view of the table to the grid. dataGrid.DataSource = dt.DefaultView; // Fill the autorefresh categories table. daRefresh = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_ConnectString"]); dtRefresh = new DataTable(CATEGORIES_TABLE); daRefresh.FillSchema(dtRefresh, SchemaType.Source); daRefresh.Fill(dtRefresh); // Bind the default view of the table to the grid. refreshDataGrid.DataSource = dtRefresh.DefaultView; // Set the refresh time for the data. dtRefresh.ExtendedProperties["RefreshTime"] = DateTime.Now.AddSeconds(DATAREFRESH_SECONDS).ToString( ); // Start the timer. timer = new System.Threading.Timer( new TimerCallback(CheckRefreshDatabase), null, DATASETCHECKREFRESHINTERVAL_MS, DATASETCHECKREFRESHINTERVAL_MS); } private void updateButton_Click(object sender, System.EventArgs e) { // Update the categories edited to the data source. da.Update(dt); } private void CheckRefreshDatabase(Object state) { DateTime now = DateTime.Now; // Check if the specified number of seconds have elapsed. if (Convert.ToDateTime(dtRefresh.ExtendedProperties ["RefreshTime"].ToString( )) < now) { // Refresh the table. daRefresh.Fill(dtRefresh); // Update the next refresh time. dtRefresh.ExtendedProperties["RefreshTime"] = now.AddSeconds(DATAREFRESH_SECONDS).ToString( ); resultTextBox.Text = "Table refreshed (" + now.ToString("T") + ")" + Environment.NewLine + resultTextBox.Text; } } DiscussionThe ExtendedProperties property accesses a PropertyCollection of custom information for a DataSet, DataTable, DataColumn, DataRelation, or Constraint object. The PropertyCollection extends the Hashtable class to store information as a collection of key-and-value pairs. The extended property data must be stored as strings; otherwise, it will not be persisted when the data is written as XML. Add items to the collection using the Add( ) method, remove them with the Remove( ) method, and access them using the indexer in C# or the Item( ) property in VB.NET. For more information about members of the PropertyCollection class, see the MSDN Library. There are three timers in the Visual Studio .NET and the .NET Framework:
The thread timer uses a ThreadCallback delegate to specify the method to execute. This delegate is specified when the Timer is constructed and cannot be changed. The method executes in a thread pool supplied by the system rather than in the thread that created the timer. When the thread timer is created, the due time (the time to wait before first execution of the method) and the period (the amount of time to wait between subsequent executions) are specified in the constructor. A due time of 0 results in the callback being invoked immediately; a due time of Timeout.Infinite results in the callback method never being invoked. A period value of 0 or Timeout.Infinite results in the callback invoked only once as long as the due time is not infinite. You can change the behavior of the timer at any time by using the Change( ) method. When the timer is no longer needed, call the Dispose( ) method to free its resources. |
[ Team LiB ] |